home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1998 May / Pcwk5b98.iso / Borland / Cplus45 / BC45 / EDIT.PAK / EDITX.CPP < prev    next >
C/C++ Source or Header  |  1995-08-29  |  15KB  |  507 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows - (C) Copyright 1991, 1993 by Borland International
  3. //----------------------------------------------------------------------------
  4. #include <owl\owlpch.h>
  5. #include <owl\applicat.h>
  6. #include <owl\framewin.h>
  7. #include <owl\static.h>
  8. #include <owl\edit.h>
  9. #include <owl\inputdia.h>
  10. #include <owl\opensave.h>
  11. #include <owl\validate.h>
  12. #include <fstream.h>
  13. #include <cstring.h>
  14.  
  15. #include "editx.rh"
  16.  
  17. // Control ids:
  18. //
  19. const int ID_EXAMPLE_EDIT       = 200;
  20.  
  21. // Message ids:
  22. //
  23. const int CN_UPDATE             = 300;
  24.  
  25. class TExampleEdit : public TEdit {
  26.   public:
  27.     TExampleEdit(TWindow*        parent,
  28.                  int             id,
  29.                  const char far* text,
  30.                  int x, int y, int w, int h,
  31.                  UINT            textLen = EditTextLen + 1,
  32.                  BOOL            multiline = TRUE,
  33.                  TModule*        module = 0 )
  34.       : TEdit(parent, id, text, x, y, w, h, textLen, multiline, module)
  35.     {
  36.       LastCBOpStr = " ";
  37.     }
  38.  
  39.     // override to setup 'FileData' structure.
  40.     //
  41.     void SetupWindow();
  42.  
  43.     // override to update text fields.
  44.     //
  45.     void    CmEditCut();                   // CM_EDITCUT
  46.     void    CmEditCopy();                  // CM_EDITCOPY
  47.     void    CmEditPaste();                 // CM_EDITPASTE
  48.     void    CmEditDelete();                // CM_EDITDELETE
  49.     void    CmEditClear();                 // CM_EDITCLEAR
  50.     void    CmEditUndo();                  // CM_EDITUNDO
  51.     void    EvKeyDown(UINT key, UINT repeatCount, UINT flags);
  52.     void    EvLButtonDown(UINT modKeys, TPoint& point);
  53.  
  54.     // Newly defined functions (not defined by base classes):
  55.     //
  56.     void NotifyParent(int notification);
  57.     void SaveText();
  58.     void RestoreText();
  59.     const string& GetLastCBOpStr() const {return LastCBOpStr;}
  60.  
  61.     string                  LastCBOpStr;   // string value of last CB operation.
  62.     static const unsigned   EditTextLen;   // length of edit control text.
  63.  
  64.   private:
  65.     TOpenSaveDialog::TData  FileData;      // save/restore info.
  66.  
  67.   DECLARE_RESPONSE_TABLE(TExampleEdit);
  68. };
  69.  
  70. DEFINE_RESPONSE_TABLE1(TExampleEdit, TEdit)
  71.   EV_COMMAND(CM_EDITCUT,     CmEditCut),
  72.   EV_COMMAND(CM_EDITCOPY,    CmEditCopy),
  73.   EV_COMMAND(CM_EDITPASTE,   CmEditPaste),
  74.   EV_COMMAND(CM_EDITDELETE,  CmEditDelete),
  75.   EV_COMMAND(CM_EDITCLEAR,   CmEditClear),
  76.   EV_COMMAND(CM_EDITUNDO,    CmEditUndo),
  77.   EV_WM_KEYDOWN,
  78.   EV_WM_LBUTTONDOWN,
  79. END_RESPONSE_TABLE;
  80.  
  81. const unsigned TExampleEdit::EditTextLen   = 1000;
  82.  
  83. void
  84. TExampleEdit::SetupWindow()
  85. {
  86.   TEdit::SetupWindow();
  87.   FileData.Flags = OFN_FILEMUSTEXIST|OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT;
  88.   FileData.SetFilter("Text files (*.TXT)|*.TXT|AllFiles (*.*)|*.*|");
  89. }
  90.  
  91. //
  92. // The next function group simply notifies the app to update the text fields
  93. // then calls the base class version to do the actual processing.
  94. //
  95.  
  96. void
  97. TExampleEdit::CmEditCut()
  98. {
  99.   LastCBOpStr = "Cut";
  100.   NotifyParent(CN_UPDATE);
  101.   TEdit::CmEditCut();
  102.   NotifyParent(CN_UPDATE);
  103.   TEdit::CmEditCut();
  104. }
  105.  
  106. void
  107. TExampleEdit::CmEditCopy()
  108. {
  109.   LastCBOpStr = "Copy";
  110.   NotifyParent(CN_UPDATE);
  111.   TEdit::CmEditCopy();
  112. }
  113.  
  114. void
  115. TExampleEdit::CmEditPaste()
  116. {
  117.   LastCBOpStr = "Paste";
  118.   NotifyParent(CN_UPDATE);
  119.   TEdit::CmEditPaste();
  120.   NotifyParent(CN_UPDATE);
  121. }
  122.  
  123. void
  124. TExampleEdit::CmEditDelete()
  125. {
  126.   LastCBOpStr = "Delete";
  127.   NotifyParent(CN_UPDATE);
  128.   TEdit::CmEditDelete();
  129.   NotifyParent(CN_UPDATE);
  130. }
  131.  
  132. void
  133. TExampleEdit::CmEditClear()
  134. {
  135.   TEdit::CmEditClear();
  136.   LastCBOpStr = "Clear";
  137.   NotifyParent(CN_UPDATE);
  138. }
  139.  
  140. void
  141. TExampleEdit::CmEditUndo()
  142. {
  143.   TEdit::CmEditUndo();
  144.   LastCBOpStr = "Undo";
  145.   NotifyParent(CN_UPDATE);
  146. }
  147.  
  148. void
  149. TExampleEdit::EvKeyDown(UINT key, UINT repeatCount, UINT flags)
  150. {
  151.   TEdit::EvKeyDown(key, repeatCount, flags);
  152.   NotifyParent(CN_UPDATE);
  153. }
  154.  
  155. void
  156. TExampleEdit::EvLButtonDown(UINT modKeys, TPoint& point)
  157. {
  158.   TEdit::EvLButtonDown(modKeys, point);
  159.   NotifyParent(CN_UPDATE);
  160. }
  161.  
  162. //
  163. // NotifyParent(). 'easy' method of notifing the parent of an event.
  164. // Notifies immediately
  165. void
  166. TExampleEdit::NotifyParent(int notification)
  167. {
  168.   Parent->SendNotification(Attr.Id, notification, HWindow);
  169. }
  170.  
  171. //
  172. // SaveText().  Save text portion of edit control to a file.
  173. //
  174. void
  175. TExampleEdit::SaveText()
  176. {
  177.   if (TFileSaveDialog(GetApplication()->MainWindow, FileData).Execute() == IDOK) {
  178.     ofstream    ofs(FileData.FileName, ios::out|ios::binary);
  179.     unsigned    maxLen = EditTextLen;
  180.     char far*   buffer = LockBuffer();
  181.     unsigned    size = min(maxLen, strlen(buffer));
  182.  
  183.     for (unsigned i = 0; i < size && buffer[i]; i++)
  184.       ofs.put(buffer[i]);
  185.     UnlockBuffer(buffer);
  186.   }
  187. }
  188.  
  189. //
  190. // RestoreText().  Restore or read in text from a file.  Uses the first
  191. // 'EditTextLen' characters from file.
  192. //
  193. void
  194. TExampleEdit::RestoreText()
  195. {
  196.   if (TFileOpenDialog(GetApplication()->MainWindow, FileData).Execute() == IDOK) {
  197.     Clear();
  198.  
  199.     ifstream    ifs(FileData.FileName);
  200.     char far*   buffer = LockBuffer(EditTextLen + 1);
  201.  
  202.     for (unsigned i = 0; i < EditTextLen && !ifs.eof(); i++) {
  203.       buffer[i] = (char)ifs.get();
  204.       if (buffer[i] == '\n' && ifs.peek() != '\r') {
  205.         buffer[i] = '\r';
  206.         buffer[++i] = '\n';
  207.       }
  208.     }
  209.     if (i)
  210.       buffer[i-1] = 0;
  211.     UnlockBuffer(buffer, TRUE);
  212.     NotifyParent(CN_UPDATE);
  213.   }
  214. }
  215.  
  216. //----------------------------------------------------------------------------
  217.  
  218. class TEditWindow : public TFrameWindow {
  219.   public:
  220.     TEditWindow(const char* title);
  221.  
  222.     void SetupWindow();
  223.  
  224.     // message response functions
  225.     //
  226.     void CmUpdate() {UpdateTextFields();} // Edit control notification.
  227.     void CmInsertText();                  // insert text at char pos.
  228.     void CmDeleteSubText();               // delete subtext.
  229.     void CmDeleteLine();                  // delete line of text.
  230.     void CmSaveText();                    // save text in edit cntl.
  231.     void CmRestoreText();                 // restore from file into edit cntl.
  232.  
  233.   private:
  234.     TExampleEdit*       EditCntl;         // edit control
  235.     TStatic*            NbrLinesText;     // text of number of lines.
  236.     TStatic*            CurLineNbrText;   // current line number.
  237.     TStatic*            CurLineText;      // current line, 1st N chars.
  238.     TStatic*            CurLineLenText;   // length of current line.
  239.     TStatic*            FirstVisibleLineText;  // line # of 1st visible line.
  240.     TStatic*            IsModifiedText;   // has edit control been modified.
  241.     TStatic*            LastCBOpText;     // last clipboard operation.
  242.     TStatic*            CurSelText;       // first N chars of selected text.
  243.  
  244.     static const unsigned   InputTextLen; // length of input text.
  245.     static const unsigned   FirstNChars;  // first n characters to display.
  246.  
  247.     void  ResetTextFields();              // reset text fields to init values.
  248.     void  UpdateTextFields();             // updates from edit control
  249.  
  250.     int                                   // read string from user.
  251.     InputString(char* prompt, char* s);
  252.  
  253.     int                                   // read number from user
  254.     InputNumber(char* prompt, unsigned& n);
  255.  
  256.   DECLARE_RESPONSE_TABLE(TEditWindow);
  257. };
  258.  
  259. DEFINE_RESPONSE_TABLE1(TEditWindow, TFrameWindow)
  260.   EV_CHILD_NOTIFY(ID_EXAMPLE_EDIT, CN_UPDATE, CmUpdate),
  261.   EV_EN_VSCROLL(ID_EXAMPLE_EDIT, CmUpdate),
  262.   EV_COMMAND(CM_INSERT_TEXT,         CmInsertText),
  263.   EV_COMMAND(CM_DELETE_SUBTEXT,      CmDeleteSubText),
  264.   EV_COMMAND(CM_DELETE_LINE,         CmDeleteLine),
  265.   EV_COMMAND(CM_SAVE_TEXT,           CmSaveText),
  266.   EV_COMMAND(CM_RESTORE_TEXT,        CmRestoreText),
  267. END_RESPONSE_TABLE;
  268.  
  269. const unsigned TEditWindow::InputTextLen  = 51;
  270. const unsigned TEditWindow::FirstNChars   = 20;
  271.  
  272. //
  273. // Constructor.  Setup menu and text areas.
  274. //
  275. TEditWindow::TEditWindow(const char* title)
  276.    : TFrameWindow(0, title), TWindow(0, title)
  277. {
  278.   const int labelStartX = 10,
  279.             textStartY = 225,
  280.             textHeight = 16,
  281.             textStartX = labelStartX + 250;
  282.  
  283.   // setup menu
  284.   //
  285.   AssignMenu("IDM_EXAMPLE_EDIT");
  286.  
  287.   // Create Edit control.
  288.   //
  289.   EditCntl = new TExampleEdit(this, ID_EXAMPLE_EDIT, "", 10, 10, 500, 200);
  290.  
  291.   // setup static text areas.
  292.   //
  293.   new TStatic(this, -1, "Number of lines:",  labelStartX, textStartY,
  294.               160, textHeight, 16);
  295.   NbrLinesText = new TStatic(this, -1, "0",  textStartX, textStartY,
  296.               50, textHeight, 5);
  297.   new TStatic(this, -1, "current line number:",  labelStartX,
  298.               textStartY + textHeight, 200, textHeight, 20);
  299.   CurLineNbrText = new TStatic(this, -1, "0",  textStartX,
  300.               textStartY + textHeight, 50, textHeight, 5);
  301.   new TStatic(this, -1, "1st 20 chars of current line:",  labelStartX,
  302.               textStartY + textHeight * 2, 290, textHeight, 29);
  303.   CurLineText = new TStatic(this, -1, "",  textStartX,
  304.               textStartY + textHeight * 2, FirstNChars * 10, textHeight,
  305.               FirstNChars);
  306.   new TStatic(this, -1, "length of current line:",  labelStartX,
  307.               textStartY + textHeight * 3, 230, textHeight, 23);
  308.   CurLineLenText = new TStatic(this, -1, "0",  textStartX,
  309.               textStartY + textHeight * 3, 50, textHeight, 5);
  310.   new TStatic(this, -1, "line number of 1st visible list:",  labelStartX,
  311.               textStartY + textHeight * 4, 320, textHeight, 32);
  312.   FirstVisibleLineText = new TStatic(this, -1, "0",  textStartX,
  313.               textStartY + textHeight * 4, 50, textHeight, 5);
  314.   new TStatic(this, -1, "has edit control been modified:",  labelStartX,
  315.               textStartY + textHeight * 5, 310, textHeight, 31);
  316.   IsModifiedText = new TStatic(this, -1, "No",  textStartX,
  317.               textStartY + textHeight * 5, 50, textHeight, 5);
  318.   new TStatic(this, -1, "last clipboard operation:",  labelStartX,
  319.               textStartY + textHeight * 6, 250, textHeight, 25);
  320.   LastCBOpText = new TStatic(this, -1, "",  textStartX,
  321.               textStartY + textHeight * 6, 100, textHeight, 10);
  322.   new TStatic(this, -1, "1st 20 chars of last selected text:",  labelStartX,
  323.               textStartY + textHeight * 7, 350, textHeight, 35);
  324.   CurSelText= new TStatic(this, -1, "",  textStartX,
  325.               textStartY + textHeight * 7, FirstNChars * 10, textHeight,
  326.               FirstNChars);
  327. }
  328.  
  329. void
  330. TEditWindow::SetupWindow()
  331. {
  332.   TFrameWindow::SetupWindow();
  333.   UpdateTextFields();
  334. }
  335.  
  336. //
  337. // CmInsertText(). Insert text at character position input be user. If pos
  338. // is beyond end of edit buffer then the insert takes place at the end of
  339. // buffer (append).
  340. //
  341. void
  342. TEditWindow::CmInsertText()
  343. {
  344.   char     buf[InputTextLen] = "";
  345.   unsigned pos;
  346.  
  347.   if (!InputNumber("Enter position:", pos))
  348.     return;
  349.   EditCntl->SetSelection(pos, pos);
  350.  
  351.   buf[0] = 0;
  352.   if (!InputString("Enter string:", buf))
  353.     return;
  354.   EditCntl->Insert(buf);
  355.   UpdateTextFields();
  356. }
  357.  
  358. //
  359. // CmDeleteSubText().  Delete characters between start position and end
  360. // position (input by user).
  361. //
  362. void
  363. TEditWindow::CmDeleteSubText()
  364. {
  365.   unsigned sPos, ePos;
  366.  
  367.   if (!InputNumber("Enter starting position", sPos))
  368.     return;
  369.  
  370.   if (!InputNumber("Enter ending position", ePos))
  371.     return;
  372.  
  373.   EditCntl->DeleteSubText(sPos, ePos);
  374.   UpdateTextFields();
  375. }
  376.  
  377. //
  378. // CmDeleteLine().  Delete line of text.  Line number input by user.
  379. //
  380. void
  381. TEditWindow::CmDeleteLine()
  382. {
  383.   unsigned line;
  384.  
  385.   if (!InputNumber("Enter line number:", line))
  386.     return;
  387.   EditCntl->DeleteLine(line);
  388.   UpdateTextFields();
  389. }
  390.  
  391. //
  392. // SaveText().  Save text of edit control to a file.
  393. //
  394. void TEditWindow::CmSaveText()
  395. {
  396.   EditCntl->SaveText();
  397. }
  398.  
  399. //
  400. // RestoreText().  retore text of edit control from a file.
  401. //
  402. void TEditWindow::CmRestoreText()
  403. {
  404.   EditCntl->RestoreText();
  405.   UpdateTextFields();
  406. }
  407.  
  408. //
  409. // UpdateTextFields(). Updates text fields that reflex the edit control's state.
  410. //
  411. void
  412. TEditWindow::UpdateTextFields()
  413. {
  414.   char        buf[FirstNChars+1] = "";
  415.   UINT        sPos, ePos, curLine;
  416.  
  417.   // get the line that the caret is currently on.
  418.   //
  419.   EditCntl->GetSelection(sPos, ePos);
  420.   curLine = EditCntl->GetLineFromPos(ePos);
  421.  
  422.   itoa(curLine, buf, 10);
  423.   CurLineNbrText->SetText(buf);
  424.  
  425.   itoa(EditCntl->GetNumLines(), buf, 10);
  426.   NbrLinesText->SetText(buf);
  427.  
  428.   EditCntl->GetLine(buf, FirstNChars, curLine);
  429.   CurLineText->SetText(buf);
  430.  
  431.   itoa(EditCntl->GetLineLength(curLine), buf, 10);
  432.   CurLineLenText->SetText(buf);
  433.  
  434.   itoa(EditCntl->GetFirstVisibleLine(), buf, 10);
  435.   FirstVisibleLineText->SetText(buf);
  436.  
  437.   if (EditCntl->IsModified())
  438.     IsModifiedText->SetText("Yes");
  439.   else
  440.     IsModifiedText->SetText("No");
  441.  
  442.   LastCBOpText->SetText(EditCntl->LastCBOpStr.c_str());
  443.  
  444.   EditCntl->GetSubText(buf, sPos, min(ePos, (unsigned)FirstNChars));
  445.   if (buf[0])
  446.     CurSelText->SetText(buf);
  447. }
  448.  
  449. //
  450. // ResetTextFields(). Reset text fields to blanks.
  451. //
  452. void
  453. TEditWindow::ResetTextFields()
  454. {
  455.   NbrLinesText->SetText("0");
  456.   CurLineNbrText->SetText("0");
  457.   CurLineText->SetText("");
  458.   CurLineLenText->SetText("0");
  459.   FirstVisibleLineText->SetText("0");
  460.   IsModifiedText->SetText("No");
  461.   LastCBOpText->SetText("");
  462.   CurSelText->SetText("");
  463. }
  464.  
  465. //
  466. // InputString(). Get string from user.  Return 1 if successful, 0 otherwise.
  467. // assumes buffer size of InputTextLen.
  468. //
  469. int
  470. TEditWindow::InputString(char* prompt, char* s)
  471. {
  472.   return TInputDialog(this, "String", prompt, s, InputTextLen).Execute() == IDOK;
  473. }
  474.  
  475. //
  476. // InputNumber(). Get number from user.  Return 1 if successful, 0 otherwise.
  477. //
  478. int
  479. TEditWindow::InputNumber(char* prompt, unsigned& n)
  480. {
  481.   char buf[10] = "";
  482.   int  ok = TInputDialog(this, "Number", prompt, buf, sizeof(buf), 0, 
  483.                          new TFilterValidator("0-9")).Execute() == IDOK;
  484.   if (ok)
  485.     n = atoi(buf);
  486.   return ok;
  487. }
  488.  
  489. //----------------------------------------------------------------------------
  490.  
  491. class TExampleEditApp : public TApplication {
  492.   public:
  493.     void  InitMainWindow();
  494. };
  495.  
  496. void
  497. TExampleEditApp::InitMainWindow()
  498. {
  499.   MainWindow = new TEditWindow("Edit Control Example");
  500. }
  501.  
  502. int
  503. OwlMain(int /*argc*/, char* /*argv*/ [])
  504. {
  505.   return TExampleEditApp().Run();
  506. }
  507.