home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c083 / 11.ddi / OWLSRC.PAK / EDITFILE.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-02  |  8.7 KB  |  358 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows - (C) Copyright 1992, 1993 by Borland International
  3. //   source\owl\editfile.cpp
  4. //   Implementation of class TEditFile, a text edit which can find/replace
  5. //   and read/write from/to a file.
  6. //----------------------------------------------------------------------------
  7. #pragma hdrignore SECTION
  8. #include <owl\owlpch.h>
  9. #include <owl\editfile.h>
  10. #include <owl\applicat.h>
  11. #include <string.h>
  12. #include <dir.h>
  13. #include <limits.h>
  14.  
  15. #if !defined(SECTION) || SECTION == 1
  16.  
  17. DEFINE_RESPONSE_TABLE1(TEditFile, TEditSearch)
  18.   EV_COMMAND(CM_FILESAVE, CmFileSave),
  19.   EV_COMMAND(CM_FILESAVEAS, CmFileSaveAs),
  20.   EV_COMMAND_ENABLE(CM_FILESAVE, CmSaveEnable),
  21. END_RESPONSE_TABLE;
  22.  
  23. //
  24. // constructor for a TEditFile
  25. //
  26. // initializes its data members using passed parameters and default values
  27. //
  28. TEditFile::TEditFile(TWindow*        parent,
  29.                      int             id,
  30.                      const char far* text,
  31.                      int x, int y, int w, int h,
  32.                      const char far* fileName,
  33.                      TModule*        module)
  34.   : TEditSearch(parent, id, text, x, y, w, h, module)
  35. {
  36.   FileName = fileName ? strnewdup(fileName) : 0;
  37. }
  38.  
  39. //
  40. // dispose of the file name
  41. //
  42. TEditFile::~TEditFile()
  43. {
  44.   delete FileName;
  45. }
  46.  
  47. //
  48. // performs setup for a TEditFile
  49. //
  50. void
  51. TEditFile::SetupWindow()
  52. {
  53.   TEditSearch::SetupWindow();
  54.   FileData.Flags = OFN_FILEMUSTEXIST|OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT;
  55.   FileData.SetFilter(string(*GetModule(), IDS_FILEFILTER).c_str());
  56.  
  57.   SetFileName(FileName);
  58.   if (FileName && !Read()) {
  59.     string msgTemplate(*GetModule(), IDS_UNABLEREAD);
  60.     char*  msg = new char[MAXPATH + msgTemplate.length()];
  61.     wsprintf(msg, msgTemplate.c_str(), FileName);
  62.     MessageBox(msg, GetApplication()->GetName(), MB_ICONEXCLAMATION | MB_OK);
  63.     delete msg;
  64.     SetFileName(0);
  65.   }
  66. }
  67.  
  68. //
  69. // sets the file name of the window and updates the caption
  70. // replacing an empty name with 'Untitled' in its caption
  71. //
  72. void
  73. TEditFile::SetFileName(const char far* fileName)
  74. {
  75.   if (fileName != FileName) {
  76.     delete FileName;
  77.     FileName = fileName ? strnewdup(fileName) : 0;
  78.   }
  79.  
  80.   string untitled(*GetModule(), IDS_UNTITLEDFILE);
  81.   const char far* p = FileName ? (const char far*)FileName : untitled.c_str();
  82.  
  83.   if (!Parent->Title || !*Parent->Title)
  84.     Parent->SetWindowText(p);
  85.  
  86.   else {
  87.     const char frmt[] = "%s - %s";
  88.     char* newCaption = new char[strlen(Parent->Title)+3+strlen(p)+1];
  89.     wsprintf(newCaption, frmt, p, Parent->Title);
  90.     Parent->SetWindowText(newCaption);
  91.     delete newCaption;
  92.   }
  93. }
  94.  
  95. //
  96. // begins the edit of a new file, after determining that it is Ok to
  97. // clear the TEdit's text
  98. //
  99. void
  100. TEditFile::NewFile()
  101. {
  102.   if (CanClear()) {
  103.     Clear();
  104.     Invalidate();
  105.     ClearModify();
  106.     SetFileName(0);
  107.   }
  108. }
  109.  
  110. //
  111. // replaces the current file with the given file
  112. //
  113. void
  114. TEditFile::ReplaceWith(const char far* fileName)
  115. {
  116.   if (Read(fileName)) {
  117.     Invalidate();
  118.     SetFileName(fileName);
  119.  
  120.   } else {
  121.     string msgTemplate(*GetModule(), IDS_UNABLEREAD);
  122.     char*  msg = new char[MAXPATH + msgTemplate.length()];
  123.     wsprintf(msg, msgTemplate.c_str(), fileName);
  124.     MessageBox(msg, GetApplication()->GetName(), MB_ICONEXCLAMATION | MB_OK);
  125.     delete msg;
  126.   }
  127. }
  128.  
  129. //
  130. // brings up a dialog allowing the user to open a file into this
  131. // window
  132. //
  133. // same as selecting File|Open from the menus
  134. //
  135. void
  136. TEditFile::Open()
  137. {
  138.   if (CanClear()) {
  139.     *FileData.FileName = 0;
  140.     if ((new TFileOpenDialog(this, FileData))->Execute() == IDOK)
  141.       ReplaceWith(FileData.FileName);
  142.   }
  143. }
  144.  
  145. //
  146. // reads the contents of a  specified file, or the previously-specified file
  147. // if no name passed, into the TEdit control
  148. // The caller is responsible for any error UI
  149. //
  150. BOOL
  151. TEditFile::Read(const char far* fileName)
  152. {
  153.   if (!fileName)
  154.     if (FileName)
  155.       fileName = FileName;
  156.     else
  157.       return FALSE;
  158.  
  159.   BOOL   success = FALSE;
  160.   HFILE  file = _lopen(fileName, OF_READ);
  161.  
  162.   if (file != HFILE_ERROR) {
  163.     long  charsToRead = _llseek(file, 0, SEEK_END);
  164.     _llseek(file, 0, SEEK_SET);
  165.  
  166.     if (charsToRead >= 0
  167.       #if !defined(__WIN32__)
  168.         && charsToRead < UINT_MAX     // limit 16bit edit ctrls to 1 segment
  169.       #endif
  170.       ) {
  171.       Clear();
  172.  
  173.       // Lock and resize Editor's buffer to the size of the file
  174.       // Then if OK, read the file into editBuffer
  175.       //
  176.       char far* editBuffer = LockBuffer(UINT(charsToRead+1));
  177.       if (editBuffer) {
  178.         if (_lread(file, editBuffer, UINT(charsToRead)) == charsToRead) {
  179.  
  180.           // 0 terminate Editor's buffer
  181.           //
  182.           editBuffer[int(charsToRead)] = 0;
  183.           success = TRUE;
  184.           ClearModify();
  185.         }
  186.         UnlockBuffer(editBuffer, TRUE);
  187.       }
  188.     }
  189.     _lclose(file);
  190.   }
  191.  
  192.   return success;
  193. }
  194.  
  195. //
  196. // saves the contents of the TEdit child control into the file currently
  197. // being editted
  198. //
  199. // returns true if the file was saved or IsModified returns FALSE
  200. //(contents already saved)
  201. //
  202. BOOL
  203. TEditFile::Save()
  204. {
  205.   if (IsModified()) {
  206.     if (!FileName)
  207.       return SaveAs();
  208.  
  209.     if (!Write()) {
  210.       string msgTemplate(*GetModule(), IDS_UNABLEWRITE);
  211.       char*  msg = new char[MAXPATH + msgTemplate.length()];
  212.       wsprintf(msg, msgTemplate.c_str(), FileName);
  213.       MessageBox(msg, GetApplication()->GetName(), MB_ICONEXCLAMATION | MB_OK);
  214.       delete msg;
  215.       return FALSE;
  216.     }
  217.   }
  218.   return TRUE;  // editor's contents haven't been changed
  219. }
  220.  
  221. //
  222. // saves the contents of the TEdit child control into a file whose name
  223. // is retrieved from the user, through execution of a "Save" file dialog
  224. //
  225. // returns true if the file was saved
  226. //
  227. BOOL
  228. TEditFile::SaveAs()
  229. {
  230.   if (FileName)
  231.     strcpy(FileData.FileName, FileName);
  232.  
  233.   else
  234.     *FileData.FileName = 0;
  235.  
  236.   if ((new TFileSaveDialog(this, FileData))->Execute() == IDOK) {
  237.     if (Write(FileData.FileName)) {
  238.       SetFileName(FileData.FileName);
  239.       return TRUE;
  240.     }
  241.     string msgTemplate(*GetModule(), IDS_UNABLEWRITE);
  242.     char*  msg = new char[MAXPATH + msgTemplate.length()];
  243.     wsprintf(msg, msgTemplate.c_str(), FileName);
  244.     MessageBox(msg, GetApplication()->GetName(), MB_ICONEXCLAMATION | MB_OK);
  245.     delete msg;
  246.   }
  247.   return FALSE;
  248. }
  249.  
  250. //
  251. // Enables save command only if text is modified
  252. //
  253. void
  254. TEditFile::CmSaveEnable(TCommandEnabler& commandHandler)
  255. {
  256.   commandHandler.Enable(IsModified());
  257. }
  258.  
  259. //
  260. // writes the contents of the TEdit child control to a specified file, or
  261. // the previously-specified file if none passed.
  262. // The caller is responsible for any error UI
  263. //
  264. BOOL
  265. TEditFile::Write(const char far* fileName)
  266. {
  267.   if (!fileName)
  268.     if (FileName)
  269.       fileName = FileName;
  270.     else
  271.       return FALSE;
  272.  
  273.   int file = _lcreat(fileName, 0);
  274.   if (file == -1) {
  275.     return FALSE;
  276.   }
  277.  
  278.   BOOL success = FALSE;
  279.   char far* editBuffer = LockBuffer();
  280.   if (editBuffer) {
  281.     success = _lwrite(file, editBuffer, strlen(editBuffer)) != (WORD)-1;
  282.     UnlockBuffer(editBuffer);
  283.     if (success)
  284.       ClearModify();
  285.   }
  286.   _lclose(file);
  287.  
  288.   return success;
  289. }
  290.  
  291. //
  292. // returns a BOOL value indicating whether or not it is Ok to clear
  293. // the TEdit's text
  294. //
  295. // returns TRUE if the text has not been changed, or if the user Oks the
  296. // clearing of the text
  297. //
  298. BOOL
  299. TEditFile::CanClear()
  300. {
  301.   if (IsModified()) {
  302.     string msgTemplate(*GetModule(), IDS_FILECHANGED);
  303.     string untitled(*GetModule(), IDS_UNTITLEDFILE);
  304.     char*  msg = new char[MAXPATH+msgTemplate.length()];
  305.  
  306.     wsprintf(msg, msgTemplate.c_str(),
  307.              FileName ? (const char far*)FileName : untitled.c_str());
  308.  
  309.     int result = MessageBox(msg, GetApplication()->GetName(), MB_YESNOCANCEL|MB_ICONQUESTION);
  310.     delete msg;
  311.     return result==IDYES ? Save() : result != IDCANCEL;
  312.   }
  313.   return TRUE;
  314. }
  315.  
  316. BOOL
  317. TEditFile::CanClose()
  318. {
  319.   return CanClear();
  320. }
  321.  
  322. #endif
  323. #if !defined(SECTION) || SECTION == 2
  324.  
  325.  
  326. IMPLEMENT_STREAMABLE1(TEditFile, TEditSearch);
  327.  
  328. //
  329. // reads an instance of TEditFile from the passed ipstream
  330. //
  331. void*
  332. TEditFile::Streamer::Read(ipstream& is, uint32 /*version*/) const
  333. {
  334.   TEditFile* o = GetObject();
  335.   ReadBaseObject((TEditSearch*)o, is);
  336.  
  337.   o->FileName = is.freadString();
  338.   if (!*o->FileName) {
  339.     delete o->FileName;
  340.     o->FileName = 0;
  341.   }
  342.   return o;
  343. }
  344.  
  345. //
  346. // writes the TEditFile to the passed opstream
  347. //
  348. void
  349. TEditFile::Streamer::Write(opstream& os) const
  350. {
  351.   TEditFile* o = GetObject();
  352.   WriteBaseObject((TEditSearch*)o, os);
  353.   os.fwriteString(o->FileName ? o->FileName : "");
  354. }
  355.  
  356. #endif
  357.  
  358.