TextFile.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737
  1. /* ==========================================================================
  2. CTextFile
  3. Author : Johan Rosengren, Abstrakt Mekanik AB
  4. Date : 2004-03-22
  5. Purpose : The class is a helper-package for text files and
  6. windows. It allows loading and saving text files in a
  7. single operation, as well as getting text to and
  8. from edit- and listboxes. If an empty filename is given
  9. as a parameter to a call, the standard file dialog will
  10. be displayed, to let the user select a file.
  11. Error handling is managed internally, and the different
  12. API-functions return a BOOL to signal success or
  13. failure. In case of failure, FALSE returned, the member
  14. function GetErrorMessage can be called to retrieve a
  15. CString with the error message.
  16. If this string is empty, the file selection was aborted
  17. in the case of an empty input name.
  18. ========================================================================
  19. 14/4 2005 Added Dave Pritchards class CStdioFileEx
  20. for MBCS/UNICODE-support.
  21. ========================================================================*/
  22. #include "stdafx.h"
  23. #include "TextFile.h"
  24. #include "../External/StdioFileEx.h"
  25. ////////////////////////////////////////
  26. // CTextFile construction/destruction
  27. CTextFile::CTextFile( const CString& ext, const CString& eol )
  28. /* ============================================================
  29. Function : CTextFile::CTextFile
  30. Description : constructor
  31. Return : void
  32. Parameters : const CString& ext - Standard extension
  33. to use in case no
  34. file name is given.
  35. const CString& eol - The end-of-line to
  36. use. Defaults to
  37. "\r\n".
  38. ============================================================*/
  39. {
  40. m_extension = ext;
  41. m_eol = eol;
  42. }
  43. CTextFile::~CTextFile()
  44. /* ============================================================
  45. Function : CTextFile::~CTextFile
  46. Description : destructor
  47. Return : void
  48. Parameters : none
  49. ============================================================*/
  50. {
  51. }
  52. ////////////////////////////////////////
  53. // CTextFile operations
  54. //
  55. BOOL CTextFile::ReadTextFile( CString& filename, CStringArray& contents )
  56. /* ============================================================
  57. Function : CTextFile::ReadTextFile
  58. Description : Will read the contents of the file filename
  59. into the CStringArray contents, one line
  60. from the file at a time.
  61. If filename is empty, the standard file
  62. dialog will be displayed, and - if OK is
  63. selected - filename will contain the
  64. selected filename on return.
  65. Return : BOOL - TRUE if OK.
  66. GetErrorMessage
  67. will contain errors.
  68. Parameters : CString& filename - file to read from
  69. CStringArray& contents - will be filled
  70. with the contents
  71. of the file
  72. ============================================================*/
  73. {
  74. ClearError();
  75. BOOL result = TRUE;
  76. if( filename.IsEmpty() )
  77. result = GetFilename( FALSE, filename );
  78. if( result )
  79. {
  80. CStdioFileEx file;
  81. CFileException feError;
  82. if( file.Open( filename, CFile::modeRead , &feError ) )
  83. {
  84. contents.RemoveAll();
  85. CString line;
  86. while( file.ReadString( line ) )
  87. contents.Add( line );
  88. file.Close();
  89. }
  90. else
  91. {
  92. TCHAR errBuff[256];
  93. feError.GetErrorMessage( errBuff, 256 );
  94. m_error = errBuff;
  95. result = FALSE;
  96. }
  97. }
  98. return result;
  99. }
  100. BOOL CTextFile::ReadTextFile( CString& filename, CString& contents )
  101. /* ============================================================
  102. Function : CTextFile::ReadTextFile
  103. Description : Will read the contents of the file filename
  104. into contents.
  105. If filename is empty, the standard file
  106. dialog will be displayed, and - if OK is
  107. selected - filename will contain the
  108. selected filename on return.
  109. Return : BOOL - TRUE if OK.
  110. GetErrorMessage will
  111. contain errors.
  112. Parameters : CString& filename - file to read from
  113. CString& contents - will be filled with
  114. the contents of the
  115. file
  116. ============================================================*/
  117. {
  118. contents = _T( "" );
  119. // Error handling
  120. ClearError();
  121. CStdioFileEx file;
  122. CFileException feError;
  123. BOOL result = TRUE;
  124. if( filename.IsEmpty() )
  125. result = GetFilename( FALSE, filename );
  126. if( result )
  127. {
  128. // Reading the file
  129. if( file.Open( filename, CFile::modeRead | CFile::typeText, &feError ) )
  130. {
  131. CString line;
  132. while( file.ReadString( line ) )
  133. contents += line + m_eol;
  134. file.Close();
  135. }
  136. else
  137. {
  138. // Setting error message
  139. TCHAR errBuff[256];
  140. feError.GetErrorMessage( errBuff, 256 );
  141. m_error = errBuff;
  142. result = FALSE;
  143. }
  144. }
  145. return result;
  146. }
  147. BOOL CTextFile::WriteTextFile( CString& filename, const CStringArray& contents )
  148. /* ============================================================
  149. Function : CTextFile::WriteTextFile
  150. Description : Writes contents to filename. Will create
  151. the file if it doesn't already exist,
  152. overwrite it otherwise.
  153. If filename is empty, the standard file
  154. dialog will be displayed, and - if OK is
  155. selected - filename will contain the
  156. selected filename on return.
  157. Return : BOOL - TRUE if OK.
  158. GetErrorMessage
  159. will return
  160. errors
  161. Parameters : CString& filename - file to
  162. write to
  163. conste CStringArray& contents - contents
  164. to write
  165. ============================================================*/
  166. {
  167. // Error handling
  168. ClearError();
  169. CStdioFileEx file;
  170. CFileException feError;
  171. BOOL result = TRUE;
  172. if(filename.IsEmpty())
  173. result = GetFilename(TRUE, filename);
  174. if(result)
  175. {
  176. // Write file
  177. if(file.Open( filename, CFile::modeWrite | CFile::modeCreate , &feError))
  178. {
  179. INT_PTR max = contents.GetSize();
  180. for(int t = 0 ; t < max ; t++)
  181. {
  182. file.WriteString(contents[t] + m_eol);
  183. }
  184. file.Close();
  185. }
  186. else
  187. {
  188. // Set error message
  189. TCHAR errBuff[256];
  190. feError.GetErrorMessage(errBuff, 256);
  191. m_error = errBuff;
  192. result = FALSE;
  193. }
  194. }
  195. return result;
  196. }
  197. BOOL CTextFile::WriteTextFile( CString& filename, const CString& contents )
  198. /* ============================================================
  199. Function : CTextFile::WriteTextFile
  200. Description : Writes contents to filename. Will create
  201. the file if it doesn't already exist,
  202. overwrite it otherwise.
  203. If filename is empty, the standard file
  204. dialog will be displayed, and - if OK is
  205. selected - filename will contain the
  206. selected filename on return.
  207. Return : BOOL - TRUE if OK.
  208. GetErrorMessage
  209. will return
  210. errors
  211. Parameters : CString& filename - file to write to
  212. const CString& contents - contents to write
  213. ============================================================*/
  214. {
  215. // Error checking
  216. ClearError();
  217. CStdioFileEx file;
  218. CFileException feError;
  219. BOOL result = TRUE;
  220. if( filename.IsEmpty() )
  221. result = GetFilename( TRUE, filename );
  222. if( result )
  223. {
  224. // Write the file
  225. if( file.Open( filename, CFile::modeWrite | CFile::modeCreate , &feError ) )
  226. {
  227. file.WriteString( contents );
  228. file.Close();
  229. }
  230. else
  231. {
  232. // Set error message
  233. TCHAR errBuff[256];
  234. feError.GetErrorMessage( errBuff, 256 );
  235. m_error = errBuff;
  236. result = FALSE;
  237. }
  238. }
  239. return result;
  240. }
  241. BOOL CTextFile::AppendFile( CString& filename, const CString& contents )
  242. /* ============================================================
  243. Function : CTextFile::AppendFile
  244. Description : Appends contents to filename. Will create
  245. the file if it doesn't already exist.
  246. If filename is empty, the standard file
  247. dialog will be displayed, and - if OK is
  248. selected - filename will contain the
  249. selected filename on return.
  250. AppendFile will not add eols.
  251. Return : BOOL - TRUE if OK.
  252. GetErrorMessage
  253. will return errors
  254. Parameters : CString& filename - file to write to
  255. const CString& contents - contents to write
  256. ============================================================*/
  257. {
  258. CFile file;
  259. CFileException feError;
  260. BOOL result = TRUE;
  261. if( filename.IsEmpty() )
  262. result = GetFilename( TRUE, filename );
  263. if( result )
  264. {
  265. // Write the file
  266. if( file.Open( filename, CFile::modeWrite | CFile::modeCreate | CFile::modeNoTruncate, &feError ) )
  267. {
  268. file.SeekToEnd();
  269. file.Write( contents, contents.GetLength() );
  270. file.Close();
  271. }
  272. else
  273. {
  274. // Set error message
  275. TCHAR errBuff[256];
  276. feError.GetErrorMessage( errBuff, 256 );
  277. m_error = errBuff;
  278. result = FALSE;
  279. }
  280. }
  281. return result;
  282. }
  283. BOOL CTextFile::AppendFile( CString& filename, const CStringArray& contents )
  284. /* ============================================================
  285. Function : CTextFile::AppendFile
  286. Description : Appends contents to filename. Will create
  287. the file if it doesn't already exist.
  288. If filename is empty, the standard file
  289. dialog will be displayed, and - if OK is
  290. selected - filename will contain the
  291. selected filename on return.
  292. Return : BOOL - TRUE if OK.
  293. GetErrorMessage
  294. will return
  295. errors
  296. Parameters : CString& filename - file to write to
  297. CStringArray contents - contents to write
  298. ============================================================*/
  299. {
  300. CStdioFileEx file;
  301. CFileException feError;
  302. BOOL result = TRUE;
  303. if(filename.IsEmpty())
  304. result = GetFilename(TRUE, filename);
  305. if(result)
  306. {
  307. // Write the file
  308. if(file.Open(filename, CFile::modeWrite | CFile::modeCreate | CFile::modeNoTruncate, &feError))
  309. {
  310. file.SeekToEnd();
  311. INT_PTR max = contents.GetSize();
  312. for(int t = 0 ; t < max ; t++)
  313. file.WriteString(contents[t] + m_eol);
  314. file.Close();
  315. }
  316. else
  317. {
  318. // Set error message
  319. TCHAR errBuff[256];
  320. feError.GetErrorMessage(errBuff, 256);
  321. m_error = errBuff;
  322. result = FALSE;
  323. }
  324. }
  325. return result;
  326. }
  327. ////////////////////////////////////////
  328. // Window operations
  329. //
  330. BOOL CTextFile::Load( CString& filename, CEdit* edit )
  331. /* ============================================================
  332. Function : CTextFile::Load
  333. Description : Loads a text file from filename to the
  334. CEdit edit.
  335. If filename is empty, the standard file
  336. dialog will be displayed, and - if OK is
  337. selected - filename will contain the
  338. selected filename on return.
  339. No translation of eols will be made.
  340. Return : BOOL - FALSE if failure.
  341. GetErrorMessage will
  342. return the error.
  343. Parameters : CString& filename - name of file to load
  344. CEdit* edit - pointer to CEdit to
  345. set text to
  346. ============================================================*/
  347. {
  348. BOOL result = FALSE;
  349. // Error checking
  350. if( ValidParam( edit ) )
  351. {
  352. CString contents;
  353. if( ReadTextFile( filename, contents ) )
  354. {
  355. edit->SetWindowText( contents );
  356. result = TRUE;
  357. }
  358. }
  359. return result;
  360. }
  361. BOOL CTextFile::Load( CString& filename, CListBox* list )
  362. /* ============================================================
  363. Function : CTextFile::Load
  364. Description : Loads a text file from filename to the
  365. CListBox list.
  366. If filename is empty, the standard file
  367. dialog will be displayed, and - if OK is
  368. selected - filename will contain the
  369. selected filename on return.
  370. Return : BOOL - FALSE if failure.
  371. GetErrorMessage will
  372. return the error.
  373. Parameters : CString& filename - name of file to load
  374. CListBox* list - pointer to CListBox
  375. to set text to
  376. ============================================================*/
  377. {
  378. BOOL result = FALSE;
  379. // Error checking
  380. if(ValidParam(list))
  381. {
  382. // Read the file
  383. CStringArray contents;
  384. if(ReadTextFile( filename, contents))
  385. {
  386. // Set to listbox
  387. INT_PTR max = contents.GetSize();
  388. for(int t = 0 ; t < max ; t++)
  389. {
  390. if(contents[t].GetLength())
  391. {
  392. list->AddString(contents[t]);
  393. }
  394. }
  395. result = TRUE;
  396. }
  397. }
  398. return result;
  399. }
  400. BOOL CTextFile::Save( CString& filename, CEdit* edit )
  401. /* ============================================================
  402. Function : CTextFile::Save
  403. Description : Saves the contents of the CEdit edit to the
  404. file filename. The file will be created or
  405. overwritten.
  406. If filename is empty, the standard file
  407. dialog will be displayed, and - if OK is
  408. selected - filename will contain the
  409. selected filename on return.
  410. Note that the eol-öarkers from the editbox
  411. will be used.
  412. Return : BOOL - FALSE if failure.
  413. GetErrorMessage will
  414. return the error.
  415. Parameters : CString& filename - name of file to save
  416. to. Will be
  417. overwritten
  418. CEdit* edit - pointer to CEdit to
  419. get text from
  420. ============================================================*/
  421. {
  422. BOOL result = FALSE;
  423. // Error checking
  424. if( ValidParam( edit ) )
  425. {
  426. // Get text
  427. CString contents;
  428. edit->GetWindowText( contents );
  429. // Write file
  430. if( WriteTextFile( filename, contents ) )
  431. result = TRUE;
  432. }
  433. return result;
  434. }
  435. BOOL CTextFile::Save( CString& filename, CListBox* list )
  436. /* ============================================================
  437. Function : CTextFile::Save
  438. Description : Saves the contents of the CListBox list to
  439. the file filename. The file will be created
  440. or overwritten.
  441. If filename is empty, the standard file
  442. dialog will be displayed, and - if OK is
  443. selected - filename will contain the
  444. selected filename on return.
  445. Return : BOOL - FALSE if failure.
  446. GetErrorMessage will
  447. return the error.
  448. Parameters : CString& filename - name of file to save
  449. to. Will be
  450. overwritten
  451. CListBox* list - pointer to CListBox
  452. to get text from
  453. ============================================================*/
  454. {
  455. BOOL result = FALSE;
  456. // Error checking
  457. if( ValidParam( list ) )
  458. {
  459. // Get listbox contents
  460. CStringArray contents;
  461. int max = list->GetCount();
  462. for( int t = 0; t < max ; t++ )
  463. {
  464. CString line;
  465. list->GetText( t, line );
  466. contents.Add( line );
  467. }
  468. // Write file
  469. if( WriteTextFile( filename, contents ) )
  470. result = TRUE;
  471. }
  472. return result;
  473. }
  474. ////////////////////////////////////////
  475. // Error handling
  476. //
  477. CString CTextFile::GetErrorMessage()
  478. /* ============================================================
  479. Function : CTextFile::GetErrorMessage
  480. Description : Retrieves the error message. Should be
  481. called after any of the file operations
  482. returns FALSE and the file name is not
  483. empty.
  484. Return : CString - The current error string
  485. Parameters : none
  486. ============================================================*/
  487. {
  488. return m_error;
  489. }
  490. ////////////////////////////////////////
  491. // Private functions
  492. //
  493. void CTextFile::ClearError()
  494. /* ============================================================
  495. Function : CTextFile::ClearError
  496. Description : Clears the internal error string. Should
  497. be called first by all functions setting
  498. the error message string.
  499. Return : void
  500. Parameters : none
  501. ============================================================*/
  502. {
  503. m_error = _T( "" );
  504. }
  505. BOOL CTextFile::ValidParam( CWnd* wnd )
  506. /* ============================================================
  507. Function : CTextFile::ValidParam
  508. Description : Used to check parameters of the Save/Load
  509. functions. The pointer to the window must
  510. be valid and the window itself must exist.
  511. Return : BOOL - FALSE if any parameter
  512. was invalid
  513. Parameters : CWnd* wnd - a window pointer, that
  514. must be valid, to a
  515. window
  516. ============================================================*/
  517. {
  518. ClearError();
  519. BOOL result = TRUE;
  520. if( wnd == NULL )
  521. {
  522. ASSERT( FALSE );
  523. result = FALSE;
  524. }
  525. if( !IsWindow( wnd->m_hWnd ) )
  526. {
  527. ASSERT( FALSE );
  528. result = FALSE;
  529. }
  530. if( !result )
  531. m_error = _T( "Bad Window handle as parameter" );
  532. return result;
  533. }
  534. BOOL CTextFile::GetFilename( BOOL save, CString& filename )
  535. /* ============================================================
  536. Function : CTextFile::GetFilename
  537. Description : The function will display a standard file
  538. dialog. If the instance is created with an
  539. extension, the extension will be used to
  540. filter files.
  541. Return : BOOL - TRUE if a file was
  542. selected
  543. Parameters : BOOL save - TRUE if the file
  544. should be saved.
  545. CString& filename - Placeholder for the
  546. selected filename
  547. ============================================================*/
  548. {
  549. CString filter;
  550. CString extension = GetExtension();
  551. if( extension.GetLength() )
  552. filter = extension + _T( "-files (*." + extension + ")|*." ) + extension + _T( "|All Files (*.*)|*.*||" );
  553. BOOL result = FALSE;
  554. CFileDialog dlg( !save, extension, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, filter );
  555. if( dlg.DoModal() == IDOK )
  556. {
  557. filename = dlg.GetPathName();
  558. result = TRUE;
  559. }
  560. return result;
  561. }
  562. CString CTextFile::GetExtension()
  563. /* ============================================================
  564. Function : CTextFile::GetExtension
  565. Description : An accessor for the m_extension field.
  566. Return : CString - the extension.
  567. Parameters : none
  568. ============================================================*/
  569. {
  570. return m_extension;
  571. }