Difference between revisions of "OOP344 20102 TextEdit"

From CDOT Wiki
Jump to: navigation, search
(Created page with '<big><big><big>TextEdit , OOP344 Open Source Project 20102</big></big></big> <big><big><big>Release 0.1</big></big></big> {{OOP344 Index}} = File Names = Save your work in se…')
 
Line 9: Line 9:
 
Save your work in separate files for each class, and name the files to the same name as the classes; each class should have a header file and a code file.
 
Save your work in separate files for each class, and name the files to the same name as the classes; each class should have a header file and a code file.
  
For example for the class [[#Field | BField]], create ''bfield.h'' and ''bfield.cpp''.  The header file should hold the class declaration, and any other possible declaration related to the class.  The "cpp" file should hold the definition (implementation) of the class, and its methods and possible functions.
+
For example for the class [[#IOField | IOField]], create ''iofield.h'' and ''iofield.cpp''.  The header file should hold the class declaration, and any other possible declaration related to the class.  The "cpp" file should hold the definition (implementation) of the class, and its methods and possible functions.
  
  
Line 18: Line 18:
 
<big>
 
<big>
 
  extern "C"{
 
  extern "C"{
  #include "biof.h"
+
  #include "iof.h"
 
  };
 
  };
 
</big>
 
</big>
  
This tells to C++ compiler, the included header file contains C functions and should be complied and called as such. Remember, you do not need and should not rename your biol.c to biol.cpp, since the compiler is already aware of the C functions in biol.c.
+
This tells to C++ compiler, the included header file contains C functions and should be complied and called as such. Remember, you do not need and should not rename your iof.c to iof.cpp, since the compiler is already aware of the C functions in iof.c.
  
 
= Header Files =
 
= Header Files =
Line 34: Line 34:
 
== General Definition Header file ==
 
== General Definition Header file ==
  
create a file called: '''btext.h'''. This file will contain any necessary definitions or possible inclusions for the project.
+
create a file called: '''iotext.h'''. This file will contain any necessary definitions or possible inclusions for the project.
  
 
This file will be included to most of your project code to carry general definitions for your project.
 
This file will be included to most of your project code to carry general definitions for your project.
  
For now add the following define statements in '''btext.h'''.
+
For now add the following define statements in '''iotext.h'''.
  
 
Keep checking this section for additions during the development of the project
 
Keep checking this section for additions during the development of the project
Line 60: Line 60:
 
  #define MAX_NO_FIELDS 500
 
  #define MAX_NO_FIELDS 500
 
  #define FRAME_CHARS  "/-\\|/-\\|"
 
  #define FRAME_CHARS  "/-\\|/-\\|"
// Release 0.3
+
  #define _CLR_AND_DSPLY_ALL -1
  #define OT_CLR_AND_DSPLY_ALL -1
+
  #define _DSPLY_ALL 0
  #define OT_DSPLY_ALL 0
 
  
// Release 0.4
 
  
 
enum MessageStatus{ClearMessage,SetMessage};
 
enum MessageStatus{ClearMessage,SetMessage};
Line 71: Line 69:
 
# undef NO_HFUNC
 
# undef NO_HFUNC
 
# endif
 
# endif
# define NO_HFUNC ((void(*)(MessageStatus, BForm&))(0))
+
# define NO_HFUNC ((void(*)(MessageStatus, IOForm&))(0))
 
# ifdef NO_VFUNC
 
# ifdef NO_VFUNC
 
# undef NO_VFUNC
 
# undef NO_VFUNC
 
# endif
 
# endif
# define NO_VFUNC ((bool(*)(const char*, BForm&))(0))
+
# define NO_VFUNC ((bool(*)(const char*, IOForm&))(0))
  
 
#endif
 
#endif
Line 88: Line 86:
 
= Mandatory Classes =
 
= Mandatory Classes =
  
To initiate development of the OpText application, we need to encapsulate the functions written in "[[BIOF 20101 (AS1) - OOP344|BIOF]]".
+
To initiate development of the TextEdit application, we need to encapsulate the functions written in "[[Oop344 20102 - iof functions|IOF]]".
  
The main design is based on the input/output objects that can be positioned on a Form. Each input/output object is responsible to encapsulate a form of entry or display: a '''Label''' to display text, a '''Line Editor''' do display and edit a character string, a '''Check Box List''' to be able to select one or many of many options, a '''Button''' to confirm actions, and etc....
+
The main design is based on the input/output objects that can be positioned on a Form. Each input/output object is responsible to encapsulate a form of entry or display: a '''Label''' to display text, a '''Line Editor''' do display and edit a character string, a '''Check Box List''' to be able to select one or many of many options, and etc....
  
Also as mentioned above, A Form object is responsible to hold the input/output objects and display and edit them in an orderly fashion. A Form, so to speak, could be an array of input/output objects.
+
Also as mentioned above, A Form object is responsible to hold the input/output objects and display and edit them in an orderly fashion. A Form, so to speak, could be an array or list of input/output objects.
  
These objects by design, could be framed, which means they can have a border drawn around them. Because of this, a class needs to be designed (we call it '''BFrame''') to represent a Frame and this class should be inherited by all Framed objects.
+
These objects by design, could be framed, which means they can have a border drawn around them. Because of this, a class needs to be designed (we call it '''IOFrame''') to represent a Frame and this class should be inherited by all Framed objects.
  
Also, the input/output objects all have the same purpose (that is displaying or editing something). This "same purpose" will be encapsulated in a class called '''BFields''' that presents the idea of an input/output object in a form.
+
Also, the input/output objects all have the same purpose (that is displaying or editing something). This "same purpose" will be encapsulated in a class called '''IOField''' that presents the idea of an input/output object in a form.
  
  
== BFrame ==
+
== IOFrame ==
  
'''BFrame''' is implemented in two files, '''bframe.h''' and '''bframe.cpp'''
+
'''IOFrame''' is implemented in two files, '''ioframe.h''' and '''ioframe.cpp'''
  
'''BFrame''' is a class encapsulating a Frame. It has a location on the Form that is its left, top coordinates (i.e. '''col''' and '''row''') also a width and a height to specify how wide and tall the frame is.
+
'''IOFrame''' is a class encapsulating a Frame. It has a location on the Form that is its left, top coordinates (i.e. '''col''' and '''row''') also a width and a height to specify how wide and tall the frame is.
  
'''BFrame''' can be invisible, which means, it will have all the specs, but it does not draw any border around itself.
+
'''IOFrame''' can be invisible, which means, it will have all the specs, but it does not draw any border around itself.
  
'''BFrame''' can obviously draw itself on the screen at a specific location with specific offset.
+
'''IOFrame''' can obviously draw itself on the screen at a specific location with specific offset.
 
 
<big><pre>
 
  
class BFrame {
+
<big><syntaxhiglight lang="cpp">
 +
class IOFrame {
 
private:
 
private:
 
   bool _visible;
 
   bool _visible;
 
   ?????
 
   ?????
// protected is removed in V0.2
 
 
   int _row;
 
   int _row;
 
   int _col;
 
   int _col;
Line 121: Line 117:
 
   int _width;
 
   int _width;
 
public:
 
public:
   BFrame(int row = -1, int col = -1,
+
   IOFrame(int row = -1, int col = -1,
 
         int height = -1, int width = -1
 
         int height = -1, int width = -1
 
         ,bool visible = false
 
         ,bool visible = false
 
         );
 
         );
  
   virtual ~BFrame();
+
   virtual ~IOFrame();
 
   void draw(int RowOffset = 0, int ColOffset = 0) const;
 
   void draw(int RowOffset = 0, int ColOffset = 0) const;
 
   void setVisible(bool visible);
 
   void setVisible(bool visible);
// V0.2
 
  
 
   void setSize(int height, int width);
 
   void setSize(int height, int width);
   virtual BFrame& row(int val);
+
   virtual IOFrame& row(int val);
   virtual BFrame& col(int val);
+
   virtual IOFrame& col(int val);
 
   virtual int row()const;
 
   virtual int row()const;
 
   virtual int col()const;
 
   virtual int col()const;
Line 140: Line 135:
 
   bool IsVisible()const;
 
   bool IsVisible()const;
 
};
 
};
</pre></big>
+
</syntaxhiglight></big>
  
'''Constructor:''' Sets the corresponding values to the incoming arguments. if any of the row, col, height or width is less than 0, then the frame will be to full-screen, which means, row and col will be set to 0 and width and height will be set to the number of columns and rows of the screen, respectively.
+
'''Constructor:''' Sets the corresponding values to the incoming arguments. if any of the row, col, height or width is less than 0, then the frame will be set to full-screen, which means, row and col will be set to 0 and width and height will be set to the number of columns and rows of the screen, respectively.
  
 
'''Destructor:''' Does Nothing. This is an empty destructor.
 
'''Destructor:''' Does Nothing. This is an empty destructor.
Line 148: Line 143:
 
'''void draw(int RowOffset = 0, int ColOffset = 0) const:''' , if the frame is visible, then it draws a rectangle on the screen with its left, top at col+ColOffset and row+RowOffset respectively. The width and height of the rectangle will be equal to the corresponding attributes in the class.
 
'''void draw(int RowOffset = 0, int ColOffset = 0) const:''' , if the frame is visible, then it draws a rectangle on the screen with its left, top at col+ColOffset and row+RowOffset respectively. The width and height of the rectangle will be equal to the corresponding attributes in the class.
  
R 0.3: Make sure the rectangle is filled with spaces.
+
note: Make sure the rectangle is filled with spaces.
  
The frame is drawn using the characters specified in  '''FRAME_CHARS''' in '''btext.h''' as follows:
+
The frame is drawn using the characters specified in  '''FRAME_CHARS''' in '''iotext.h''' as follows:
<big>
+
<big><pre>
 
  Index        Character
 
  Index        Character
 
   0          left-top
 
   0          left-top
Line 161: Line 156:
 
   6          bottom-left
 
   6          bottom-left
 
   7          left border
 
   7          left border
</big>
+
</pre></big>
  
 
In full screen mode the four corners are not printed.
 
In full screen mode the four corners are not printed.
Line 169: Line 164:
 
*'''void setSize(int height, int width);''' Sets the _height and _width to the incoming values
 
*'''void setSize(int height, int width);''' Sets the _height and _width to the incoming values
  
*'''virtual BFrame& row(int val);''' Sets the _row to incoming '''val''' and then returns a reference of BFrame
+
*'''virtual IOFrame& row(int val);''' Sets the _row to incoming '''val''' and then returns a reference of IOFrame
  
*'''virtual BFrame& col(int val);''' Sets the _col to incoming '''val''' and then returns a reference of BFrame
+
*'''virtual IOFrame& col(int val);''' Sets the _col to incoming '''val''' and then returns a reference of IOFrame
  
 
*'''virtual int row()const;''' returns the value of _row
 
*'''virtual int row()const;''' returns the value of _row
Line 181: Line 176:
 
*'''virtual int width()const;''' return the value of _width
 
*'''virtual int width()const;''' return the value of _width
  
*'''bool IsVisible()const;''' returns the status of BFrame, true, if the frame is visible and false if it is not
+
*'''bool IsVisible()const;''' returns the status of IOFrame, true, if the frame is visible and false if it is not
Here is how a BFrame looks like when it is drawn:
+
Here is how a IOFrame looks like when it is drawn:
  
 
[[File:BFrame.gif]]
 
[[File:BFrame.gif]]
  
 
<br />
 
<br />
[http://pastebin.ca/1823508 A main() function to test BFrame::draw Offsets]<br />
+
[[OOP344 20102 IOFrame test main|A main() function to test IOFrame::draw Offsets]]<br />
  
bframe executable sample on matrix: ~fardad.soleimanloo/bframetest
 
  
== BField ==
+
== IOField ==
  
''' BField ''' represents an input/output object. It is a Framed object, which means it '''publicly''' inherits BField.
+
''' IOField ''' represents an input/output object. It is a Framed object, which means it '''publicly''' inherits IOFrame.
  
BField is what is common between all the input/output fields in this system. BField is the base of every and each of the input/output fields.
+
IOField is what is common between all the input/output fields in this system. IOField is the base of every and each of the input/output fields.
  
A BField is usually an element of a Form Entity (see BForm). Because of this, for each Field to be able to post messages on the Form, it needs to have a reference to the Form it is on.
+
An IOField is usually an element of a Form Entity (see IOForm). Because of this, for each Field to be able to post messages on the Form, it needs to have a reference to the Form it is on.
  
Each BField gets its location (row and col) and its size (height and width) from its grandparent BFrame.
+
Each IOField gets its location (row and col) and its size (height and width) from its parent IOFrame.
  
Because BField is to do input/output, it needs a general way to be able to hold/keep track of the data it is inputting or outputting.
+
Because IOField is to do input/output, it needs a general way to be able to hold/keep track of the data it is inputting or outputting.
  
 
To accommodate the above we create the following class:
 
To accommodate the above we create the following class:
 
<big><pre>
 
<big><pre>
  
# include "bframe.h"
+
# include "ioframe.h"
  
class BForm;
+
class IOForm;
//R0.3 private inheritance changed to public
+
 
class BField: public BFrame{
+
class IOField: public IOFrame{
 
private:
 
private:
   BForm* _owner;
+
   IOForm* _owner;
 
protected:
 
protected:
 
   void* _data;
 
   void* _data;
 
public:
 
public:
   BField(int row = 0, int col = 0,
+
   IOField(int row = 0, int col = 0,
 
         void* data = (void*) 0, bool framed = false
 
         void* data = (void*) 0, bool framed = false
 
   );
 
   );
   virtual ~BField();
+
   virtual ~IOField();
 
   virtual void display() const;
 
   virtual void display() const;
 
   virtual int edit() = 0;
 
   virtual int edit() = 0;
 
   virtual bool editable() const = 0;
 
   virtual bool editable() const = 0;
 
   virtual void* data();
 
   virtual void* data();
//  void setOwner(BForm* owner); is renamed in V0.2
 
  
   void set(BForm* owner);
+
   void set(IOForm* owner);
 
   int row()const;
 
   int row()const;
 
   int col()const;
 
   int col()const;
// added in R 0.2:
 
 
   int height()const;
 
   int height()const;
 
   int width()const;
 
   int width()const;
  
// added in R 0.3
+
   virtual IOField& set(const void* data) = 0;
 
 
   virtual BField& set(const void* data) = 0;
 
 
 
// added in R 0.4
 
  
   BForm* owner();
+
   IOForm* owner();
  
 
};
 
};
Line 245: Line 233:
 
</pre></big>
 
</pre></big>
  
* '''_owner''' Holds the address of the Form the BField Belongs to. If null, it means the BField does not belong to any Form and it is stand alone
+
* '''_owner''' Holds the address of the Form the IOField Belongs to. If null, it means the IOField does not belong to any Form and it is stand alone
  
 
* '''_data''' Holds the address of the data being edited by this IO Field.
 
* '''_data''' Holds the address of the data being edited by this IO Field.
  
* '''BField(int row = 0, int col = 0, void* data = (void*) 0, bool framed = false);''' Passes row and col to BFrame and also passes 0 to BFrame for height and width. Then the constructor sets the _data address to incoming data address and sets the _owner to null.
+
* '''IOField(int row = 0, int col = 0, void* data = (void*) 0, bool framed = false);''' Passes row and col to IOFrame and also passes 0 to IOFrame for height and width. Then the constructor sets the _data address to incoming data address and sets the _owner to null.
  
Since a BField has ONLY what is common between different IO Fields, it can not have the final say on several of its own values. For example, the height and width depends of type of the IO it is going to be.
+
Since a IOField has ONLY what is common between different IO Fields, it can not have the final say on several of its own values. For example, the height and width depends of type of the IO it is going to be.
  
* '''virtual ~BField();''' Does nothing.
+
* '''virtual ~IOField();''' Does nothing.
  
* '''virtual void display() const;''' Depending to be an element of a Form (see BForm) or be a stand alone IO Field, it does the following:
+
* '''virtual void display() const;''' Depending to be an element of a Form (see IOForm) or be a stand alone IO Field, it does the following:
  
If the the BField's _owner attribute is null (it is not an element on a Form, or better to say it does not belong to a Form), it calls BFrame::draw() with no arguments, otherwise(if _owner is not null) it calls the BFrame::draw() passing its the _owner's row and col as offset arguments.
+
If the the IOField's _owner attribute is null (it is not an element on a Form, or better to say it does not belong to a Form), it calls IOFrame::draw() with no arguments, otherwise(if _owner is not null) it calls the IOFrame::draw() passing its the _owner's row and col as offset arguments.
''By doing this, if BField is an element on a form, its location becomes relative to the Form it is in and not the screen''
+
''By doing this, if IOField is an element on a form, its location becomes relative to the Form it is in and not the screen''
  
 
* '''virtual int edit() = 0;''' Enforces the children to have an edit method
 
* '''virtual int edit() = 0;''' Enforces the children to have an edit method
Line 266: Line 254:
 
* '''virtual void* data();''' Returns the value the _data attribute
 
* '''virtual void* data();''' Returns the value the _data attribute
  
* '''void set(BForm* owner);''' Sets the _owner attribute to incoming owner address. (this method will be used by BForm to become the owner of the BFields being added it)
+
* '''void set(IOForm* owner);''' Sets the _owner attribute to incoming owner address. (this method will be used by IOForm to become the owner of the IOFields being added it)
  
* '''int row()const;''' Returns the row of the BFrame, but if the _owner is not null, the value of the row of the _owner will be added to returned value.
+
* '''int row()const;''' Returns the row of the IOFrame, but if the _owner is not null, the value of the row of the _owner will be added to returned value.
  
* '''int col()const;''' Returns the col of the BFrame, but if the _owner is not null, the value of the col of the _owner will be added to returned value.
+
* '''int col()const;''' Returns the col of the IOFrame, but if the _owner is not null, the value of the col of the _owner will be added to returned value.
  
* '''int height()const;''' Returns the height of the BFrame.
+
* '''int height()const;''' Returns the height of the IOFrame.
  
* '''int width()const;''' Returns the width of the BFrame.
+
* '''int width()const;''' Returns the width of the IOFrame.
* '''R0.3: virtual BField& set(const void* data) = 0;''' Enforces the children to have a set method for setting the value of _data.
+
* '''R0.3: virtual IOField& set(const void* data) = 0;''' Enforces the children to have a set method for setting the value of _data.
  
* '''R0.4: BForm* owner();''' returns the value of the '''_owner''' attribute.
+
* '''R0.4: IOForm* owner();''' returns the value of the '''_owner''' attribute.
  
 
== BLabel ==
 
== BLabel ==
  
BLabel is a BField to display a string of characters. It essentially encapsulates bio_display().
+
BLabel is a IOField to display a string of characters. It essentially encapsulates bio_display().
  
 
The only attribute BLabel need in addition to its parents is an integer to Hold the length of the string to be shown.
 
The only attribute BLabel need in addition to its parents is an integer to Hold the length of the string to be shown.
  
 
<big><pre>
 
<big><pre>
  #include "bfield.h"
+
  #include "IOField.h"
  class BLabel: public BField{
+
  class BLabel: public IOField{
 
   int _length;
 
   int _length;
 
  public:
 
  public:
Line 298: Line 286:
  
 
   // modified in R0.3
 
   // modified in R0.3
   BField& set(const void* str);
+
   IOField& set(const void* str);
 
  };
 
  };
 
</pre></big>
 
</pre></big>
Line 306: Line 294:
 
Allocation should be done after setting the '''_length''' to the proper value; if len is less than or equal to zero, then '''_length''' will be set to the length of the '''str''', otherwise, '''_length''' will be set to the value of incoming '''len'''.
 
Allocation should be done after setting the '''_length''' to the proper value; if len is less than or equal to zero, then '''_length''' will be set to the length of the '''str''', otherwise, '''_length''' will be set to the value of incoming '''len'''.
  
After this, '''_length +1 ''' chars should be allocated and it address should be kept in '''BField::_data'''
+
After this, '''_length +1 ''' chars should be allocated and it address should be kept in '''IOField::_data'''
  
Then the contents of str should be copied up to _legnth chars into '''BField::_data'''.  Make sure that the string is null terminated.
+
Then the contents of str should be copied up to _legnth chars into '''IOField::_data'''.  Make sure that the string is null terminated.
  
 
*'''BLabel(int row, int col, int len);'''
 
*'''BLabel(int row, int col, int len);'''
Line 314: Line 302:
 
This constructor is used to create an empty BLabel. It works exactly like the above constructor, with one difference; there is no string to initialize the newly allocated memory.
 
This constructor is used to create an empty BLabel. It works exactly like the above constructor, with one difference; there is no string to initialize the newly allocated memory.
  
'''_length''' is set to incoming '''len''' and then '''BField::_data''' is set to the address of the newly allocated '''_length +1 ''' chars.  
+
'''_length''' is set to incoming '''len''' and then '''IOField::_data''' is set to the address of the newly allocated '''_length +1 ''' chars.  
  
 
Set the first char of the _data to null to set the string to blank.
 
Set the first char of the _data to null to set the string to blank.
  
*'''virtual ~BLabel();''' Deletes the data held in BField::_data
+
*'''virtual ~BLabel();''' Deletes the data held in IOField::_data
  
*'''void display() const;'''  Using bio_display, displays BField::_data at BField::row() and BField::col(), up to _length characters  
+
*'''void display() const;'''  Using bio_display, displays IOField::_data at IOField::row() and IOField::col(), up to _length characters  
  
 
*'''int edit();''' Calls the display() method and returns 0.
 
*'''int edit();''' Calls the display() method and returns 0.
Line 326: Line 314:
 
*'''bool editable()const;''' Always return false
 
*'''bool editable()const;''' Always return false
  
*'''BField& set(const void* str);''' Copies the '''str''' into BField::_data up to _length chars and then returns a reference of the BLabel.
+
*'''IOField& set(const void* str);''' Copies the '''str''' into IOField::_data up to _length chars and then returns a reference of the BLabel.
  
 
== BEdit ==
 
== BEdit ==
BEdit is A BField that is responsible to encapsulate the bio_edit.
+
BEdit is A IOField that is responsible to encapsulate the bio_edit.
  
 
To do so in addition to the attributes of its parents; row, col and width (that is fieldlen) it needs to have the following:
 
To do so in addition to the attributes of its parents; row, col and width (that is fieldlen) it needs to have the following:
Line 338: Line 326:
 
*An integer pointer to hold the address of the insert status.
 
*An integer pointer to hold the address of the insert status.
 
<big><pre>
 
<big><pre>
class BEdit: public BField{
+
class BEdit: public IOField{
 
   bool _dyn;
 
   bool _dyn;
 
   int _maxdatalen;
 
   int _maxdatalen;
Line 361: Line 349:
  
 
   //Modified in R0.3
 
   //Modified in R0.3
   BField& set(const void* str);
+
   IOField& set(const void* str);
 
};
 
};
 
</pre></big>
 
</pre></big>
 
*'''BEdit(char* str, int row, int col, int fieldlen,int maxdatalen, int* insertmode,bool framed = false);'''
 
*'''BEdit(char* str, int row, int col, int fieldlen,int maxdatalen, int* insertmode,bool framed = false);'''
  
Edit, sets BField::_data to value of str. If BEdit is instantiated with this constructor then it will edit an external string provided by the caller function of BEdit. BEdit in this case is not creating any dynamic memory, therefore '''_dyn''' is set to false;  
+
Edit, sets IOField::_data to value of str. If BEdit is instantiated with this constructor then it will edit an external string provided by the caller function of BEdit. BEdit in this case is not creating any dynamic memory, therefore '''_dyn''' is set to false;  
 
The location (row and col) and '''framed''' are directly passed to the parent and str is passed as data to the parent constructor.
 
The location (row and col) and '''framed''' are directly passed to the parent and str is passed as data to the parent constructor.
 
Unlike BLabel, BEdit could be framed or not so depending on this (framed being true or false) the size (width and height) of BEdit are set as follows:
 
Unlike BLabel, BEdit could be framed or not so depending on this (framed being true or false) the size (width and height) of BEdit are set as follows:
Line 384: Line 372:
 
*'''BEdit(int row, int col, int fieldlen,int maxdatalen, int* insertmode,bool framed = false);''' This Constructor works exactly like the above with respect to location and size, but for data, because no data is provided to edit, it will create a dynamic, blank char string to accommodate the editing.
 
*'''BEdit(int row, int col, int fieldlen,int maxdatalen, int* insertmode,bool framed = false);''' This Constructor works exactly like the above with respect to location and size, but for data, because no data is provided to edit, it will create a dynamic, blank char string to accommodate the editing.
  
the size of the allocation will be maxdatelen +1 and obviously _dyn is set to true, so the destructor knows the memory has to be deallocated at the time of destruction. The allocated memory should be pointed by BField::_data.
+
the size of the allocation will be maxdatelen +1 and obviously _dyn is set to true, so the destructor knows the memory has to be deallocated at the time of destruction. The allocated memory should be pointed by IOField::_data.
*'''~BEdit();''' If _dyn is true it will delete the string pointed by BField::_data.
+
*'''~BEdit();''' If _dyn is true it will delete the string pointed by IOField::_data.
  
 
*'''void display()const;''' First it will call the display() method of its parent and then makes a direct call to bio_display using the row(), col() and fieldlen() accessors.
 
*'''void display()const;''' First it will call the display() method of its parent and then makes a direct call to bio_display using the row(), col() and fieldlen() accessors.
 
*'''int edit();''' makes a direct call to bio_edit passing the corresponding values from the attributes and accessor methods. the IsTextEditor is set t '''0''' and the readonly is set to '''0''' too (for now).
 
*'''int edit();''' makes a direct call to bio_edit passing the corresponding values from the attributes and accessor methods. the IsTextEditor is set t '''0''' and the readonly is set to '''0''' too (for now).
 
*'''bool editable()const;''' returns true
 
*'''bool editable()const;''' returns true
*'''int row()const;''' returns the BField::row() but it will add one to it, if BEdit is framed
+
*'''int row()const;''' returns the IOField::row() but it will add one to it, if BEdit is framed
*'''int col()const;''' returns the BField::col() but it will add one to it, if BEdit is framed
+
*'''int col()const;''' returns the IOField::col() but it will add one to it, if BEdit is framed
*'''int fieldlen()const;''' returns the BFrame::width() but reduces it by 2 if BEdit is framed
+
*'''int fieldlen()const;''' returns the IOFrame::width() but reduces it by 2 if BEdit is framed
*'''BField& set(const void* str);''' copies the content of str into BField::_data up to maxdatalen characters.
+
*'''IOField& set(const void* str);''' copies the content of str into IOField::_data up to maxdatalen characters.
  
  
== BForm ==
+
== IOForm ==
  
BForm is a collection of BFields. BForm organizes and groups the BFields for user entry.
+
IOForm is a collection of IOFields. IOForm organizes and groups the IOFields for user entry.
  
 
<big><pre>
 
<big><pre>
  
# include "btext.h"
+
# include "iotext.h"
  
class BFrame;
+
class IOFrame;
class BField;
+
class IOField;
  
class BForm: public BFrame{
+
class IOForm: public IOFrame{
 
private:
 
private:
 
int _fnum;
 
int _fnum;
 
int _curidx;
 
int _curidx;
BField* _fld[MAX_NO_FIELDS];
+
IOField* _fld[MAX_NO_FIELDS];
 
bool _dyn[MAX_NO_FIELDS];
 
bool _dyn[MAX_NO_FIELDS];
 
bool _editable;
 
bool _editable;
BForm* _owner;
+
IOForm* _owner;
 
public:
 
public:
BForm(int row = -1, int col = -1, int width = -1,
+
IOForm(int row = -1, int col = -1, int width = -1,
 
int height = -1, bool framed = false);
 
int height = -1, bool framed = false);
virtual ~BForm();
+
virtual ~IOForm();
 
void display(int fn = OT_CLR_AND_DSPLY_ALL)const;
 
void display(int fn = OT_CLR_AND_DSPLY_ALL)const;
int edit(int fn = 0, BForm* owner = (BForm*)0);
+
int edit(int fn = 0, IOForm* owner = (IOForm*)0);
BForm& add(BField* field, bool dynamic = true);
+
IOForm& add(IOField* field, bool dynamic = true);
BForm& add(BField& field, bool dynamic = false);
+
IOForm& add(IOField& field, bool dynamic = false);
 
bool editable();
 
bool editable();
 
int fieldNum()const;
 
int fieldNum()const;
 
int curField()const;
 
int curField()const;
BForm& set(BForm* owner);
+
IOForm& set(IOForm* owner);
  
BField& operator[](unsigned int index);
+
IOField& operator[](unsigned int index);
 
};
 
};
  
 
</pre></big>
 
</pre></big>
  
* '''_fnum''' is the number of BFields added to the BForm
+
* '''_fnum''' is the number of IOFields added to the IOForm
  
* '''_curidx''' is the index of the current BField being edited.
+
* '''_curidx''' is the index of the current IOField being edited.
  
* '''_fld''' is an array of BField pointers. Initially all the elements of _fld is set to null. When a BField is added to the form, it will be pointed by one of the elements of this array.
+
* '''_fld''' is an array of IOField pointers. Initially all the elements of _fld is set to null. When a IOField is added to the form, it will be pointed by one of the elements of this array.
  
* '''_dyn''' is an array of boolean values exactly to the number of elements of '''_fld'''. When BField number '''"n"''' is added to BForm and is pointed by '''_fld[n-1]''' , the corresponding '''_dyn[n-1]''' indicate if the BField held in '''_fld[n-1]''' is dynamically allocated or not. the '''_dyn''' flags will be used in the destructor as deallocation condition for each _fld element.
+
* '''_dyn''' is an array of boolean values exactly to the number of elements of '''_fld'''. When IOField number '''"n"''' is added to IOForm and is pointed by '''_fld[n-1]''' , the corresponding '''_dyn[n-1]''' indicate if the IOField held in '''_fld[n-1]''' is dynamically allocated or not. the '''_dyn''' flags will be used in the destructor as deallocation condition for each _fld element.
  
* '''_editable''' is set to true, if at least one of the BFields in '''_fld''' is editable.
+
* '''_editable''' is set to true, if at least one of the IOFields in '''_fld''' is editable.
  
* '''_owner''', If a BForm is being used by another BForm, then the '''_owner''' of the used BForm will be set to the user-BForm.
+
* '''_owner''', If a IOForm is being used by another IOForm, then the '''_owner''' of the used IOForm will be set to the user-IOForm.
  
* '''BForm(int row = -1, int col = -1, int width = -1, int height = -1, bool framed = false);''', creates a BForm. It passes the coordinates (row and col) and size (width and height) and also the framed flag to its parent BFrame.
+
* '''IOForm(int row = -1, int col = -1, int width = -1, int height = -1, bool framed = false);''', creates a IOForm. It passes the coordinates (row and col) and size (width and height) and also the framed flag to its parent IOFrame.
  
Then it will set all the '''_fld''' elements to null, '''_fnum''' to 0 (empty BForm), _editable to false and _curidx to 0 and _owner to (BForm*) 0;
+
Then it will set all the '''_fld''' elements to null, '''_fnum''' to 0 (empty IOForm), _editable to false and _curidx to 0 and _owner to (IOForm*) 0;
  
* '''~BForm()''' goes through all '''_fld''' elements from 0 to '''_fnum''', if the corresponding '''_dyn''' element is true, it will then delete the BField pointed by that '''_fld''' element.
+
* '''~IOForm()''' goes through all '''_fld''' elements from 0 to '''_fnum''', if the corresponding '''_dyn''' element is true, it will then delete the IOField pointed by that '''_fld''' element.
  
 
* '''void display(int fn = 0)const;'''<br />
 
* '''void display(int fn = 0)const;'''<br />
Line 455: Line 443:
 
If '''fn''' is OT_CLR_AND_DSPLY_ALL, then it will check to see if _owner is not null. If _owner is not null, it will call the _owner's display() with OT_CLR_AND_DSPLY_ALL, otherwise it will just clear the screen.<br />
 
If '''fn''' is OT_CLR_AND_DSPLY_ALL, then it will check to see if _owner is not null. If _owner is not null, it will call the _owner's display() with OT_CLR_AND_DSPLY_ALL, otherwise it will just clear the screen.<br />
  
Then it first call BFrame::draw() and then it will display all the _fld elements, one by one.
+
Then it first call IOFrame::draw() and then it will display all the _fld elements, one by one.
  
If '''fn''' is OT_DSPLY_ALL then it will just call BFrame::draw() and then it will display all the _fld elements, one by one.<br />
+
If '''fn''' is OT_DSPLY_ALL then it will just call IOFrame::draw() and then it will display all the _fld elements, one by one.<br />
 
If '''fn''' is greater than 0 then it will only display '''_fld''' number '''fn''' (_fld[fn-1])
 
If '''fn''' is greater than 0 then it will only display '''_fld''' number '''fn''' (_fld[fn-1])
  
* '''int edit(int fn = 0, BForm* owner = (BForm*)0);''' Edits  First it will set '''_owner''' to incoming '''owner''' argument. <br />
+
* '''int edit(int fn = 0, IOForm* owner = (IOForm*)0);''' Edits  First it will set '''_owner''' to incoming '''owner''' argument. <br />
  
If BForm is not editable (all fields are non-editable), it will just display the BForm and then waits for the user to enter a key and then terminates the function returning the key.<br />
+
If IOForm is not editable (all fields are non-editable), it will just display the IOForm and then waits for the user to enter a key and then terminates the function returning the key.<br />
If fn is '''0''' then before editing, the whole form is displayed and editing begins from the first editable BField.
+
If fn is '''0''' then before editing, the whole form is displayed and editing begins from the first editable IOField.
  
If fn is greater than '''0''' then editing begins from the first editable key on or after BField number '''fn'''.
+
If fn is greater than '''0''' then editing begins from the first editable key on or after IOField number '''fn'''.
  
 
Note that fn is the sequence number of field and not the index.
 
Note that fn is the sequence number of field and not the index.
Line 473: Line 461:
 
Call the edit of each field and depending on the value returned, do the following:
 
Call the edit of each field and depending on the value returned, do the following:
  
# For '''ENTER_KEY''', '''TAB_KEY''' and '''DOWN_KEY''', go to next editable BField , if this is the last editable BField then restart from BField number one.
+
# For '''ENTER_KEY''', '''TAB_KEY''' and '''DOWN_KEY''', go to next editable IOField , if this is the last editable IOField then restart from IOField number one.
# For '''UP_KEY''' go to the previous editable BField, if there is no previous editable BField, go to the last editable BField in the BForm.
+
# For '''UP_KEY''' go to the previous editable IOField, if there is no previous editable IOField, go to the last editable IOField in the IOForm.
 
# For any other key, terminate the edit function returning the character which caused the termination.
 
# For any other key, terminate the edit function returning the character which caused the termination.
  
* '''BForm& add(BField* field, bool dynamic = true);''' adds value of the field pointer to the _fld array , sets the corresponding _dyn element to the value of dynamic argument and then increases _fnum by one.
+
* '''IOForm& add(IOField* field, bool dynamic = true);''' adds value of the field pointer to the _fld array , sets the corresponding _dyn element to the value of dynamic argument and then increases _fnum by one.
  
By doing this a BField is added to the collection of BFields in BForm::_fld.
+
By doing this a IOField is added to the collection of IOFields in IOForm::_fld.
It also sets the _owner of the added BField to this BForm.
+
It also sets the _owner of the added IOField to this IOForm.
Note that this BField is dynamic by default
+
Note that this IOField is dynamic by default
  
* '''BForm& add(BField& field, bool dynamic = false);''' adds address of the field pointer to the _fld array , sets the corresponding _dyn element to the value of dynamic argument and then increases _fnum by one.
+
* '''IOForm& add(IOField& field, bool dynamic = false);''' adds address of the field pointer to the _fld array , sets the corresponding _dyn element to the value of dynamic argument and then increases _fnum by one.
  
By doing this a BField is added to the collection of BFields in BForm::_fld.
+
By doing this a IOField is added to the collection of IOFields in IOForm::_fld.
It also sets the _owner of the added BField to this BForm.
+
It also sets the _owner of the added IOField to this IOForm.
Note that this BField is non-dynamic by default.
+
Note that this IOField is non-dynamic by default.
  
* '''bool editable();''' Returns true if at least one of the BFields added to the BForm is editable.
+
* '''bool editable();''' Returns true if at least one of the IOFields added to the IOForm is editable.
 
* '''int fieldNum()const;''' returns _fnum
 
* '''int fieldNum()const;''' returns _fnum
  
 
* '''int curField()const;''' returns _curidx
 
* '''int curField()const;''' returns _curidx
* '''BForm& set(BForm* owner);''' Sets the '''_owner''' to the incoming owner argument
+
* '''IOForm& set(IOForm* owner);''' Sets the '''_owner''' to the incoming owner argument
* '''BField& operator[](unsigned int index);''' returns the reference of the _fld[index], if index is larger than _fnum, then circle back from the beginning.<br />
+
* '''IOField& operator[](unsigned int index);''' returns the reference of the _fld[index], if index is larger than _fnum, then circle back from the beginning.<br />
 
Executable sample for optext Release 0.3: ~fardad.soleimanloo/optext0.3
 
Executable sample for optext Release 0.3: ~fardad.soleimanloo/optext0.3
  
Line 500: Line 488:
  
 
= BVedit =
 
= BVedit =
Before coding this class, apply "Release 0.4" changes to '''btext.h''' and '''BField''' class and then
+
Before coding this class, apply "Release 0.4" changes to '''iotext.h''' and '''IOField''' class and then
  
 
Inherit BEdit class to a Validated line editor class called BVedit.
 
Inherit BEdit class to a Validated line editor class called BVedit.
Line 508: Line 496:
 
BVedit has two extra attributes that are pointers to Validation and Help functions:
 
BVedit has two extra attributes that are pointers to Validation and Help functions:
 
<big><pre>
 
<big><pre>
   void (*_help)(MessageStatus, BForm&);
+
   void (*_help)(MessageStatus, IOForm&);
   bool (*_validate)(const char*, BForm&);
+
   bool (*_validate)(const char*, IOForm&);
 
</pre></big>
 
</pre></big>
  
Line 518: Line 506:
 
   BVedit(int row, int col, int fieldlen,
 
   BVedit(int row, int col, int fieldlen,
 
     int maxdatalen, int* insertmode,
 
     int maxdatalen, int* insertmode,
     bool (*validate)(const char* , BForm&) = NO_VFUNC,
+
     bool (*validate)(const char* , IOForm&) = NO_VFUNC,
     void (*help)(MessageStatus, BForm&) = NO_HFUNC,
+
     void (*help)(MessageStatus, IOForm&) = NO_HFUNC,
 
     bool framed = false);
 
     bool framed = false);
 
   BVedit(char* str, int row, int col, int fieldlen,
 
   BVedit(char* str, int row, int col, int fieldlen,
 
     int maxdatalen, int* insertmode,
 
     int maxdatalen, int* insertmode,
     bool (*validate)(const char* , BForm&) = NO_VFUNC,
+
     bool (*validate)(const char* , IOForm&) = NO_VFUNC,
     void (*help)(MessageStatus, BForm&) = NO_HFUNC,
+
     void (*help)(MessageStatus, IOForm&) = NO_HFUNC,
 
   bool framed = false);
 
   bool framed = false);
  
Line 548: Line 536:
 
= BTextEdit =
 
= BTextEdit =
  
BTextEdit is inherited from BField and edits a multi-line text as a text editor.
+
BTextEdit is inherited from IOField and edits a multi-line text as a text editor.
  
 
== Constructors ==
 
== Constructors ==
Line 559: Line 547:
 
       bool readonly, int* insertmode);
 
       bool readonly, int* insertmode);
 
</pre></big>
 
</pre></big>
BTextEdit is created using its coordinates on the BForm (row, col) and the height and width of the text area, for editing the text.
+
BTextEdit is created using its coordinates on the IOForm (row, col) and the height and width of the text area, for editing the text.
  
 
The maximum width of the text could be considered constant that is defined in '''OT_MAX_LINE_CHARS'''.
 
The maximum width of the text could be considered constant that is defined in '''OT_MAX_LINE_CHARS'''.
Line 604: Line 592:
 
returns true;
 
returns true;
 
<big><pre>
 
<big><pre>
   BField& set(const void *str);
+
   IOField& set(const void *str);
 
</pre></big>
 
</pre></big>
  
Line 626: Line 614:
 
= Test Programs =
 
= Test Programs =
  
[[OpText Test Programs - OOP344 20101 | OpText Test Programs]]
+
[[TextEdit Test Programs - OOP344 20101 | TextEdit Test Programs]]
  
 
= Class Hierarchy =
 
= Class Hierarchy =
Line 632: Line 620:
 
<big><pre>
 
<big><pre>
  
BFrame
+
IOFrame
 
  |
 
  |
  |---BForm
+
  |---IOForm
 
  |
 
  |
 
  |
 
  |
  |---BField
+
  |---IOField
 
       |
 
       |
 
       |--------BLabel
 
       |--------BLabel
Line 650: Line 638:
 
= Due Dates =
 
= Due Dates =
  
Due Date for the OpText Application 0.5 Release (Final), Sat, Apr 24th 23:59.
+
Due Date for the TextEdit Application 0.5 Release (Final), Sat, Apr 24th 23:59.
  
 
For task due dates, look for each team's individual project development page in the [[Project 20101 OOP344|Main Project Page]]
 
For task due dates, look for each team's individual project development page in the [[Project 20101 OOP344|Main Project Page]]
Line 669: Line 657:
  
 
<big><pre>
 
<big><pre>
optext: biof.o bframe.o bfield.o blabel.o bedit.o bform.o optext.o
+
optext: biof.o ioframe.o IOField.o blabel.o bedit.o bform.o optext.o
         c++ biof.o bframe.o bfield.o blabel.o bedit.o bform.o optext.o \
+
         c++ biof.o ioframe.o IOField.o blabel.o bedit.o bform.o optext.o \
 
   -lncurses -ooptext
 
   -lncurses -ooptext
  
Line 676: Line 664:
 
         cc -c biof.c
 
         cc -c biof.c
  
bframe.o: bframe.cpp bframe.h btext.h
+
ioframe.o: ioframe.cpp ioframe.h iotext.h
         c++ -c bframe.cpp  
+
         c++ -c ioframe.cpp  
  
bfield.o: bfield.cpp bfield.h bframe.h bform.h   
+
IOField.o: IOField.cpp IOField.h ioframe.h bform.h   
         c++ -c bfield.cpp  
+
         c++ -c IOField.cpp  
  
blabel.o: blabel.cpp blabel.h bfield.h btext.h
+
blabel.o: blabel.cpp blabel.h IOField.h iotext.h
 
         c++ -c blabel.cpp  
 
         c++ -c blabel.cpp  
  
bedit.o: bedit.cpp bedit.h bfield.h btext.h
+
bedit.o: bedit.cpp bedit.h IOField.h iotext.h
 
         c++ -c bedit.cpp  
 
         c++ -c bedit.cpp  
  
bform.o: bform.cpp bform.h btext.h bfield.h
+
bform.o: bform.cpp bform.h iotext.h IOField.h
 
         c++ -c bform.cpp  
 
         c++ -c bform.cpp  
  
optext.o: optext.cpp btext.h blabel.h bedit.h bform.h bfield.h
+
optext.o: optext.cpp iotext.h blabel.h bedit.h bform.h IOField.h
 
         c++ -c optext.cpp  
 
         c++ -c optext.cpp  
  
 
</pre></big>
 
</pre></big>

Revision as of 08:11, 23 June 2010

TextEdit , OOP344 Open Source Project 20102

Release 0.1


OOP344 | Weekly Schedule | Student List | Teams | Project | Student Resources

File Names

Save your work in separate files for each class, and name the files to the same name as the classes; each class should have a header file and a code file.

For example for the class IOField, create iofield.h and iofield.cpp. The header file should hold the class declaration, and any other possible declaration related to the class. The "cpp" file should hold the definition (implementation) of the class, and its methods and possible functions.


How to reuse your C code in C++ programs

Include your already existing C code into your C++ code as follows:

extern "C"{
#include "iof.h"
};

This tells to C++ compiler, the included header file contains C functions and should be complied and called as such. Remember, you do not need and should not rename your iof.c to iof.cpp, since the compiler is already aware of the C functions in iof.c.

Header Files

General Definition Header file

create a file called: iotext.h. This file will contain any necessary definitions or possible inclusions for the project.

This file will be included to most of your project code to carry general definitions for your project.

For now add the following define statements in iotext.h.

Keep checking this section for additions during the development of the project


 #ifndef __BIO_BTEXT_H__
 #define __BIO_BTEXT_H__

 extern "C"{
 #include "biof.h"
 };

 #ifndef _CRT_SECURE_NO_DEPRECATE
 #define _CRT_SECURE_NO_DEPRECATE
 #endif
 #ifndef _CRT_SECURE_NO_WARNINGS
 #define _CRT_SECURE_NO_WARNINGS
 #endif
 #define MAX_NO_FIELDS 500
 #define FRAME_CHARS  "/-\\|/-\\|"
 #define _CLR_AND_DSPLY_ALL -1
 #define _DSPLY_ALL 0


enum MessageStatus{ClearMessage,SetMessage};

# ifdef NO_HFUNC
# undef NO_HFUNC
# endif
# define NO_HFUNC ((void(*)(MessageStatus, IOForm&))(0))
# ifdef NO_VFUNC
# undef NO_VFUNC
# endif
# define NO_VFUNC ((bool(*)(const char*, IOForm&))(0))

#endif

How to include header files to prevent circular inclusion

SVN Quick Notes

Mandatory Classes

To initiate development of the TextEdit application, we need to encapsulate the functions written in "IOF".

The main design is based on the input/output objects that can be positioned on a Form. Each input/output object is responsible to encapsulate a form of entry or display: a Label to display text, a Line Editor do display and edit a character string, a Check Box List to be able to select one or many of many options, and etc....

Also as mentioned above, A Form object is responsible to hold the input/output objects and display and edit them in an orderly fashion. A Form, so to speak, could be an array or list of input/output objects.

These objects by design, could be framed, which means they can have a border drawn around them. Because of this, a class needs to be designed (we call it IOFrame) to represent a Frame and this class should be inherited by all Framed objects.

Also, the input/output objects all have the same purpose (that is displaying or editing something). This "same purpose" will be encapsulated in a class called IOField that presents the idea of an input/output object in a form.


IOFrame

IOFrame is implemented in two files, ioframe.h and ioframe.cpp

IOFrame is a class encapsulating a Frame. It has a location on the Form that is its left, top coordinates (i.e. col and row) also a width and a height to specify how wide and tall the frame is.

IOFrame can be invisible, which means, it will have all the specs, but it does not draw any border around itself.

IOFrame can obviously draw itself on the screen at a specific location with specific offset.

<syntaxhiglight lang="cpp"> class IOFrame { private:

 bool _visible;
 ?????
 int _row;
 int _col;
 int _height;
 int _width;

public:

 IOFrame(int row = -1, int col = -1,
        int height = -1, int width = -1
        ,bool visible = false
        );
 virtual ~IOFrame();
 void draw(int RowOffset = 0, int ColOffset = 0) const;
 void setVisible(bool visible);
 void setSize(int height, int width);
 virtual IOFrame& row(int val);
 virtual IOFrame& col(int val);
 virtual int row()const;
 virtual int col()const;
 virtual int height()const;
 virtual int width()const;
 bool IsVisible()const;

}; </syntaxhiglight>

Constructor: Sets the corresponding values to the incoming arguments. if any of the row, col, height or width is less than 0, then the frame will be set to full-screen, which means, row and col will be set to 0 and width and height will be set to the number of columns and rows of the screen, respectively.

Destructor: Does Nothing. This is an empty destructor.

void draw(int RowOffset = 0, int ColOffset = 0) const: , if the frame is visible, then it draws a rectangle on the screen with its left, top at col+ColOffset and row+RowOffset respectively. The width and height of the rectangle will be equal to the corresponding attributes in the class.

note: Make sure the rectangle is filled with spaces.

The frame is drawn using the characters specified in FRAME_CHARS in iotext.h as follows:

 Index        Character
   0          left-top
   1          top border
   2          top-right
   3          right border
   4          right-bottom
   5          bottom border
   6          bottom-left
   7          left border

In full screen mode the four corners are not printed.

  • void setVisible(bool visible): Sets the visible attribute to the incoming argument.
  • void setSize(int height, int width); Sets the _height and _width to the incoming values
  • virtual IOFrame& row(int val); Sets the _row to incoming val and then returns a reference of IOFrame
  • virtual IOFrame& col(int val); Sets the _col to incoming val and then returns a reference of IOFrame
  • virtual int row()const; returns the value of _row
  • virtual int col()const; returns the value of _col
  • virtual int height()const; returns the value of _height
  • virtual int width()const; return the value of _width
  • bool IsVisible()const; returns the status of IOFrame, true, if the frame is visible and false if it is not

Here is how a IOFrame looks like when it is drawn:

BFrame.gif


A main() function to test IOFrame::draw Offsets


IOField

IOField represents an input/output object. It is a Framed object, which means it publicly inherits IOFrame.

IOField is what is common between all the input/output fields in this system. IOField is the base of every and each of the input/output fields.

An IOField is usually an element of a Form Entity (see IOForm). Because of this, for each Field to be able to post messages on the Form, it needs to have a reference to the Form it is on.

Each IOField gets its location (row and col) and its size (height and width) from its parent IOFrame.

Because IOField is to do input/output, it needs a general way to be able to hold/keep track of the data it is inputting or outputting.

To accommodate the above we create the following class:


# include "ioframe.h"

class IOForm;

class IOField: public IOFrame{
private:
  IOForm* _owner;
protected:
  void* _data;
public:
  IOField(int row = 0, int col = 0,
         void* data = (void*) 0, bool framed = false
  );
  virtual ~IOField();
  virtual void display() const;
  virtual int edit() = 0;
  virtual bool editable() const = 0;
  virtual void* data();

  void set(IOForm* owner);
  int row()const;
  int col()const;
  int height()const;
  int width()const;

  virtual IOField& set(const void* data) = 0;

  IOForm* owner();

};

  • _owner Holds the address of the Form the IOField Belongs to. If null, it means the IOField does not belong to any Form and it is stand alone
  • _data Holds the address of the data being edited by this IO Field.
  • IOField(int row = 0, int col = 0, void* data = (void*) 0, bool framed = false); Passes row and col to IOFrame and also passes 0 to IOFrame for height and width. Then the constructor sets the _data address to incoming data address and sets the _owner to null.

Since a IOField has ONLY what is common between different IO Fields, it can not have the final say on several of its own values. For example, the height and width depends of type of the IO it is going to be.

  • virtual ~IOField(); Does nothing.
  • virtual void display() const; Depending to be an element of a Form (see IOForm) or be a stand alone IO Field, it does the following:

If the the IOField's _owner attribute is null (it is not an element on a Form, or better to say it does not belong to a Form), it calls IOFrame::draw() with no arguments, otherwise(if _owner is not null) it calls the IOFrame::draw() passing its the _owner's row and col as offset arguments. By doing this, if IOField is an element on a form, its location becomes relative to the Form it is in and not the screen

  • virtual int edit() = 0; Enforces the children to have an edit method
  • virtual bool editable()const = 0; Enforces the children to specify if they are editable or not
  • virtual void* data(); Returns the value the _data attribute
  • void set(IOForm* owner); Sets the _owner attribute to incoming owner address. (this method will be used by IOForm to become the owner of the IOFields being added it)
  • int row()const; Returns the row of the IOFrame, but if the _owner is not null, the value of the row of the _owner will be added to returned value.
  • int col()const; Returns the col of the IOFrame, but if the _owner is not null, the value of the col of the _owner will be added to returned value.
  • int height()const; Returns the height of the IOFrame.
  • int width()const; Returns the width of the IOFrame.
  • R0.3: virtual IOField& set(const void* data) = 0; Enforces the children to have a set method for setting the value of _data.
  • R0.4: IOForm* owner(); returns the value of the _owner attribute.

BLabel

BLabel is a IOField to display a string of characters. It essentially encapsulates bio_display().

The only attribute BLabel need in addition to its parents is an integer to Hold the length of the string to be shown.

 #include "IOField.h"
 class BLabel: public IOField{
   int _length;
 public:
   BLabel(const char *str, int row, int col, int len = 0);
   BLabel(int row, int col, int len);
   virtual ~BLabel();
   void display() const;
   int edit();
   bool editable()const;

   // modified in R0.3
   IOField& set(const void* str);
 };
  • BLabel(const char *str, int row, int col, int len = 0); After passing row and col to its parent, it allocates memory to hold the contents of str.

Allocation should be done after setting the _length to the proper value; if len is less than or equal to zero, then _length will be set to the length of the str, otherwise, _length will be set to the value of incoming len.

After this, _length +1 chars should be allocated and it address should be kept in IOField::_data

Then the contents of str should be copied up to _legnth chars into IOField::_data. Make sure that the string is null terminated.

  • BLabel(int row, int col, int len);

This constructor is used to create an empty BLabel. It works exactly like the above constructor, with one difference; there is no string to initialize the newly allocated memory.

_length is set to incoming len and then IOField::_data is set to the address of the newly allocated _length +1 chars.

Set the first char of the _data to null to set the string to blank.

  • virtual ~BLabel(); Deletes the data held in IOField::_data
  • void display() const; Using bio_display, displays IOField::_data at IOField::row() and IOField::col(), up to _length characters
  • int edit(); Calls the display() method and returns 0.
  • bool editable()const; Always return false
  • IOField& set(const void* str); Copies the str into IOField::_data up to _length chars and then returns a reference of the BLabel.

BEdit

BEdit is A IOField that is responsible to encapsulate the bio_edit.

To do so in addition to the attributes of its parents; row, col and width (that is fieldlen) it needs to have the following:

  • A flag to keep the status of memory allocation (if memory allocation is being used or not)
  • An integer to keep the maximum data len.
  • An integer to keep the cursor position.
  • An integer to keep the offset position.
  • An integer pointer to hold the address of the insert status.
class BEdit: public IOField{
  bool _dyn;
  int _maxdatalen;
  int* _insertmode;
  int _curpos;
  int _offset;
public:
  BEdit(char* str, int row, int col, int fieldlen,
    int maxdatalen, int* insertmode, 
    bool framed = false);
  BEdit(int row, int col, int fieldlen,
    int maxdatalen, int* insertmode,
    bool framed = false);
  ~BEdit();
  void display()const;
  
  int edit();
  bool editable()const;
  int row()const;
  int col()const;
  int fieldlen()const;

  //Modified in R0.3
  IOField& set(const void* str);
};
  • BEdit(char* str, int row, int col, int fieldlen,int maxdatalen, int* insertmode,bool framed = false);

Edit, sets IOField::_data to value of str. If BEdit is instantiated with this constructor then it will edit an external string provided by the caller function of BEdit. BEdit in this case is not creating any dynamic memory, therefore _dyn is set to false; The location (row and col) and framed are directly passed to the parent and str is passed as data to the parent constructor. Unlike BLabel, BEdit could be framed or not so depending on this (framed being true or false) the size (width and height) of BEdit are set as follows:

If framed is false, then there is no border around the editing line so the height of the frame should be set to 0 and the width of the frame should be equal to the value of fieldlen. How ever is the editing line is bordered, then it needs 3 chars for height and fieldlen + 2 as width:


/-------------------\
|Editing line here  |
\-------------------/


  • BEdit(int row, int col, int fieldlen,int maxdatalen, int* insertmode,bool framed = false); This Constructor works exactly like the above with respect to location and size, but for data, because no data is provided to edit, it will create a dynamic, blank char string to accommodate the editing.

the size of the allocation will be maxdatelen +1 and obviously _dyn is set to true, so the destructor knows the memory has to be deallocated at the time of destruction. The allocated memory should be pointed by IOField::_data.

  • ~BEdit(); If _dyn is true it will delete the string pointed by IOField::_data.
  • void display()const; First it will call the display() method of its parent and then makes a direct call to bio_display using the row(), col() and fieldlen() accessors.
  • int edit(); makes a direct call to bio_edit passing the corresponding values from the attributes and accessor methods. the IsTextEditor is set t 0 and the readonly is set to 0 too (for now).
  • bool editable()const; returns true
  • int row()const; returns the IOField::row() but it will add one to it, if BEdit is framed
  • int col()const; returns the IOField::col() but it will add one to it, if BEdit is framed
  • int fieldlen()const; returns the IOFrame::width() but reduces it by 2 if BEdit is framed
  • IOField& set(const void* str); copies the content of str into IOField::_data up to maxdatalen characters.


IOForm

IOForm is a collection of IOFields. IOForm organizes and groups the IOFields for user entry.


# include "iotext.h"

class IOFrame;
class IOField;

class IOForm: public IOFrame{
private:
int _fnum;
int _curidx;
IOField* _fld[MAX_NO_FIELDS];
bool _dyn[MAX_NO_FIELDS];
bool _editable;
IOForm* _owner;
public:
IOForm(int row = -1, int col = -1, int width = -1,
int height = -1, bool framed = false);
virtual ~IOForm();
void display(int fn = OT_CLR_AND_DSPLY_ALL)const;
int edit(int fn = 0, IOForm* owner = (IOForm*)0);
IOForm& add(IOField* field, bool dynamic = true);
IOForm& add(IOField& field, bool dynamic = false);
bool editable();
int fieldNum()const;
int curField()const;
IOForm& set(IOForm* owner);

IOField& operator[](unsigned int index);
};

  • _fnum is the number of IOFields added to the IOForm
  • _curidx is the index of the current IOField being edited.
  • _fld is an array of IOField pointers. Initially all the elements of _fld is set to null. When a IOField is added to the form, it will be pointed by one of the elements of this array.
  • _dyn is an array of boolean values exactly to the number of elements of _fld. When IOField number "n" is added to IOForm and is pointed by _fld[n-1] , the corresponding _dyn[n-1] indicate if the IOField held in _fld[n-1] is dynamically allocated or not. the _dyn flags will be used in the destructor as deallocation condition for each _fld element.
  • _editable is set to true, if at least one of the IOFields in _fld is editable.
  • _owner, If a IOForm is being used by another IOForm, then the _owner of the used IOForm will be set to the user-IOForm.
  • IOForm(int row = -1, int col = -1, int width = -1, int height = -1, bool framed = false);, creates a IOForm. It passes the coordinates (row and col) and size (width and height) and also the framed flag to its parent IOFrame.

Then it will set all the _fld elements to null, _fnum to 0 (empty IOForm), _editable to false and _curidx to 0 and _owner to (IOForm*) 0;

  • ~IOForm() goes through all _fld elements from 0 to _fnum, if the corresponding _dyn element is true, it will then delete the IOField pointed by that _fld element.
  • void display(int fn = 0)const;

If fn is OT_CLR_AND_DSPLY_ALL, then it will check to see if _owner is not null. If _owner is not null, it will call the _owner's display() with OT_CLR_AND_DSPLY_ALL, otherwise it will just clear the screen.

Then it first call IOFrame::draw() and then it will display all the _fld elements, one by one.

If fn is OT_DSPLY_ALL then it will just call IOFrame::draw() and then it will display all the _fld elements, one by one.
If fn is greater than 0 then it will only display _fld number fn (_fld[fn-1])

  • int edit(int fn = 0, IOForm* owner = (IOForm*)0); Edits First it will set _owner to incoming owner argument.

If IOForm is not editable (all fields are non-editable), it will just display the IOForm and then waits for the user to enter a key and then terminates the function returning the key.
If fn is 0 then before editing, the whole form is displayed and editing begins from the first editable IOField.

If fn is greater than 0 then editing begins from the first editable key on or after IOField number fn.

Note that fn is the sequence number of field and not the index.

Start editing from field number fn;

Call the edit of each field and depending on the value returned, do the following:

  1. For ENTER_KEY, TAB_KEY and DOWN_KEY, go to next editable IOField , if this is the last editable IOField then restart from IOField number one.
  2. For UP_KEY go to the previous editable IOField, if there is no previous editable IOField, go to the last editable IOField in the IOForm.
  3. For any other key, terminate the edit function returning the character which caused the termination.
  • IOForm& add(IOField* field, bool dynamic = true); adds value of the field pointer to the _fld array , sets the corresponding _dyn element to the value of dynamic argument and then increases _fnum by one.

By doing this a IOField is added to the collection of IOFields in IOForm::_fld. It also sets the _owner of the added IOField to this IOForm. Note that this IOField is dynamic by default

  • IOForm& add(IOField& field, bool dynamic = false); adds address of the field pointer to the _fld array , sets the corresponding _dyn element to the value of dynamic argument and then increases _fnum by one.

By doing this a IOField is added to the collection of IOFields in IOForm::_fld. It also sets the _owner of the added IOField to this IOForm. Note that this IOField is non-dynamic by default.

  • bool editable(); Returns true if at least one of the IOFields added to the IOForm is editable.
  • int fieldNum()const; returns _fnum
  • int curField()const; returns _curidx
  • IOForm& set(IOForm* owner); Sets the _owner to the incoming owner argument
  • IOField& operator[](unsigned int index); returns the reference of the _fld[index], if index is larger than _fnum, then circle back from the beginning.

Executable sample for optext Release 0.3: ~fardad.soleimanloo/optext0.3


BVedit

Before coding this class, apply "Release 0.4" changes to iotext.h and IOField class and then

Inherit BEdit class to a Validated line editor class called BVedit.

BVedit, works exactly like a BEdit, with two differences; 1- It supports Help messages. 2- Supports data validation

BVedit has two extra attributes that are pointers to Validation and Help functions:

  void (*_help)(MessageStatus, IOForm&);
  bool (*_validate)(const char*, IOForm&);

Constructors


  BVedit(int row, int col, int fieldlen,
    int maxdatalen, int* insertmode,
    bool (*validate)(const char* , IOForm&) = NO_VFUNC,
    void (*help)(MessageStatus, IOForm&) = NO_HFUNC,
    bool framed = false);
  BVedit(char* str, int row, int col, int fieldlen,
    int maxdatalen, int* insertmode,
    bool (*validate)(const char* , IOForm&) = NO_VFUNC,
    void (*help)(MessageStatus, IOForm&) = NO_HFUNC,
   bool framed = false);

These two constructors pass all the information directly to BEdit's constructor and then set the "function pointers" attributes to their corresponding arguments.

Public Function


 int edit();

  • if owner() of BVedit is null, then it simply calls the BEdit's edit() and terminates (returning the same value as BEdit::edit())
  • if owner() is not null
    • if the help function pointer attribute is not NULL, it will call it passing SetMesssage , and *owner()' as arguments (This will show the help message for this field, before editing begins.)
    • if the validation function pointer is not null then it will call the BEdit::edit() and validate the data with it by keep repeating the BEdit::edit() until either validation function return true or the BEdit::edit() was terminated by a non navigation key.
      • Navigation keys are: UP_KEY DOWN_KEY TAB_KEY and ENTER_KEY
    • Right before the BVedit::edit() Terminates, if the help function pointer attribute is not NULL, it will call it again passing ClearMesssage , and owner()' as arguments (this will clear the help message after editing is done.)
    • BVedit::edit() will return the return value of BEdit::edit().

BTextEdit

BTextEdit is inherited from IOField and edits a multi-line text as a text editor.

Constructors

  BTextEdit(int row, int col,  int height,int width,
      bool readonly, int* insertmode);
  BTextEdit(const char* str,
            int row, int col,  int height,int width,
      bool readonly, int* insertmode);

BTextEdit is created using its coordinates on the IOForm (row, col) and the height and width of the text area, for editing the text.

The maximum width of the text could be considered constant that is defined in OT_MAX_LINE_CHARS.

There is no limit to the number for lines in the text.

The first constructor creates the class with an empty text that is edited by the user.The second constructor creates the class and then initializes the text with incoming str argument.

If readonly is true then text can be browsed but not edited.


Public Methods

  void display()const;

Displays the text within the text area.

  void *data();

Returns the address of a single dimension char array holding the edited text.

  int edit();

Edits the text. Use a simple text editor like NLED to get an idea what capabilities you can add to your text editor. Minimum requirement:

  • Full scroll and edit capability
  • Inserting new line (when enter is hit in a line, a new line is added after the current line)
  • Removing a line (when backspace is hit at the beginning of a line

If you have doubts about the behavior of edit method, check any text editor and replicate its behavior.

  bool  editable()const;

returns true;

  IOField& set(const void *str);

Sets the data of BTextEdit to the incomming data in the character array pointed by str.

  bool readOnly();

Returns, if BTextEdit is read-only or not.

  virtual ~BTextEdit();

Deallocates the dynamic memory used by the class before BTextEdit is destroyed.


The Application

Using the above classes, create a Text Editor that is capable of creating a new text file or opening an already existing one for edit and save or save with new name.

Test Programs

TextEdit Test Programs

Class Hierarchy


IOFrame
 |
 |---IOForm
 |
 |
 |---IOField
       |
       |--------BLabel
       |
       |--------BEdit
       |         |
       |         |-------BVedit
       |
       |--------BTextEdit

Due Dates

Due Date for the TextEdit Application 0.5 Release (Final), Sat, Apr 24th 23:59.

For task due dates, look for each team's individual project development page in the Main Project Page

Executable Samples on Matrix

  • Bframe test: ~fardad.soleimanloo/bframetest
  • optext Release 0.3: ~fardad.soleimanloo/optext0.3

compiling under Linux

To compile in matrix, use: g++ yada.cpp yadoo.cpp -x c biof.c -lncurses If you have many cpp's, you may also do g++ *.cpp -x c biof.c -lncurses

Sample makefile for optext release 0.3

optext: biof.o ioframe.o IOField.o blabel.o bedit.o bform.o optext.o
        c++ biof.o ioframe.o IOField.o blabel.o bedit.o bform.o optext.o \
   -lncurses -ooptext

biof.o: biof.c biof.h
        cc -c biof.c

ioframe.o: ioframe.cpp ioframe.h iotext.h
        c++ -c ioframe.cpp 

IOField.o: IOField.cpp IOField.h ioframe.h bform.h   
        c++ -c IOField.cpp 

blabel.o: blabel.cpp blabel.h IOField.h iotext.h
        c++ -c blabel.cpp 

bedit.o: bedit.cpp bedit.h IOField.h iotext.h
        c++ -c bedit.cpp 

bform.o: bform.cpp bform.h iotext.h IOField.h
         c++ -c bform.cpp 

optext.o: optext.cpp iotext.h blabel.h bedit.h bform.h IOField.h
         c++ -c optext.cpp