Changes

Jump to: navigation, search

OOP344 Assignment Two

3,342 bytes added, 13:15, 17 April 2013
m
Undo revision 69911 by MCanaday49 (Talk) - SPAM
[[OOP344]] - [[OOP344 Student List]] - [[OOP344 Teams]] - [[OOP344 Assignment One]] - [[OOP344 Assignment Two]] - [[OOP344 IRC Schedules 20093 |OOP344 IRC Schedules]]<br />
- [[OOP344 Student Resources]]<br />
Under construction...
=Due Dates=
 
*Saturday, November 28th: Version 0.1 (Initial working version)
 
*Tuesday, December 8th: Version 1.0 (Working version)
 
*Tuesday, December 8th to Thursday, December 17th: Final debugging and IRC meetings
=File Names=
Save your work in separate files for each class. Name , and name the files to the same name as the classes. Each ; each class should have a header file and a code file.
For example for the class IOField[[#IO_Field | IO_Field]], create iofield''IO_Field.h '' and iofield''IO_Field.cpp''. The header file should hold the class declaration , and any other possible declaration related to the class. the The "cpp" file should hold the definition (implementation) of the class , and its methods and possible functions.
Create a Make file to build your project with respect to dependencies of classes.
 
=SVN Quick Notes=
# Checkout the code $svn co svn://zenit.senecac.on.ca/ops344_093aXXops344_093a'''XX'''/trunk/PRJ --username yourUserName <sup>Remember, '''XX''' is your SVN number after your section ('a' etc.)</sup>
# Add selected ciol.h ciol.cpp and if present the class files (all compiled) $svn add filename
# Commit the new files $svn commit
[[OOP344_Team_++ | Team ++ website]]
[[ OOP344 Group3 BINGO | Team BINGO]]
[[ OOP344_Temporary | Team Temporary Name ]]
[[ OOP344_Hasselhoff | Team Hasselhoff ]]
 
=General Definition Header file=
create a file called: '''io_def.h'''. This file will contain any necessary definitions or inclusions for the project.
for now add the following define statements in '''io_def.h'''
<big><pre>
#define _FRAME_UNDERLINE " - "
#define _FRAME_UNDEROVER " - - "
#define _FRAME_LISTS "|/-\\|/-\\-/"
#define _FRAME_MENUS "|+-+|+-+"
#define _RADIOLIST_CHARS "(o)"
#define _MENU_CHARS "[]"
#define _IO_TEXT_ALLOCATION_LINE_SIZE 1024
#ifdef NO_FUNC
void* _data;
IO_Form* _owner;
int getOwnerTop(void)const;
int getOwnerLeft(void)const;
void displayOwner(void)const;
public:
IO_Field(int row, int col, void* data = (void*)0);
This constructor sets the corresponding attributes to the values of incoming arguments.
===Protected Methods===
====getOwnerTop and left (optional)====
<big><pre>
int getOwnerTop()const;
int getOwnerLeft()const;
</pre></big>
These two methods return the top and left, coordinates of the frame of the form in which the field exists.They simply return zero, if there is no owner. This can help the display methods of a field to place the field at the correct, relative position according to the form they are displayed in.
====displayOwner() (optional)====
<big><pre>
void displayOwner()const;
</pre></big>
This method displays the owner of a field, if it exists. This can help a Field to hide itself, by displaying the owner, without displaying itself.
===Public Methods===
 
====data()====
<big><pre>
virtual void* data();
</pre></big>
Returns the value of the data attribute.
===Destructor===
'''<big><pre>'''virtual ~IOField();'''</pre></big>'''
An empty destructor (the body of the method is blank)
 
===Pure Virtual Methods===
<big><pre>
returns the '''_left''' attribute;
 
====getTop()====
 
<big><pre>
int getTop();
returns the '''_top''' attribute;
 
====void set()====
<big><pre>
void set(int top, int left);
==IO_Form==
'''[[#IO_Frame| IO_Frame]]''' is inherited into a container class called '''IO_Form'''. '''IO_Form''' organizes the '''[[#IO_Field | IO_Field]]''' classes and give the user a panel to use them sequentially.
'''IO_Form''' should be able to hold unlimited number of '''[[#IO_Field | IO_Fields]]'''. (Use either a dynamic array, or linked list structure of '''[[#IO_Field | IO_Fields]]''' to implement this)
<hr width="50%" />
===Constructor===
int add(IO_Field* f, bool dynamic, bool submitter);
</pre></big>
'''IO_Form''' uses this private '''add''' method to provide means of adding fields through several public add methods. this method adds an '''[[#IO_Field | IO_Field]]''' to the end of the '''[[#IO_Field | IO_Fields ]]''' in the IO_Form;
*'''f''' : is Is the address of the '''[[#IO_Field | IO_Field]]''' begin added to the '''IO_Form'''*'''dynamic''' : if If set to true, it sets this '''[[#IO_Field | IO_Field]]''' to be deallocated by '''IO_Form''''s destructor at the end;*'''submitter''': if If set to true, it tags this '''[[#IO_Field | IO_Field]]''' to terminate the '''IO_Form''''s edit() if ENTER_KEY is hit. see the edit() method for more info.
'''add()''' also calls '''set(IO_Form* owner)''' of '''[[#IO_Field | IO_Field]]''' and passes its pointer ''(this)'' to it. By doing this, each '''[[#IO_Field | IO_Field]]''' will know who is its owner.
'''add()''' returns the number of fields currently in IO_FORM.
<hr width="50%" />
int add(IO_Field* f, bool submitter = false);
</pre></big>
Uses the private add() method to add a dynamic IO_field'''[[#IO_Field | IO_Field]]'''.
<hr width="50%" />
<big><pre>
int add(IO_Field& f, bool submitter = false);
</pre></big>
Uses the private add() method to add a non-dynamic IO_field'''[[#IO_Field | IO_Field]]'''.
<hr width="50%" />
<big><pre>
int addHelp(IO_Label* L);
</pre></big>
Uses the private add() method to add a dynamic IO_field '''[[#IO_Field | IO_Field]]''' and also saves its address for the general help message label of the Form.
<hr width="50%" />
<big><pre>
int addHelp(IO_Label& L);
</pre></big>
Uses the private add() method to add a non-dynamic IO_field '''[[#IO_Field | IO_Field]]''' and also saves its address for the general help message label of the Form.
<hr width="50%" />
<big><pre>
int addError(IO_Label* L);
</pre></big>
Uses the private add() method to add a dynamic IO_field '''[[#IO_Field | IO_Field]]''' and also saves its address for the general error message label of the Form.
<hr width="50%" />
<big><pre>
int addError(IO_Label& L);
</pre></big>
Uses the private add() method to add a non-dynamic IO_field '''[[#IO_Field | IO_Field]]''' and also saves its address for the general error message label of the Form.
<hr width="50%" />
<big><pre>
</pre></big>
Uses the private add() method to add a non-submitter, dynamic IO_field'''[[#IO_Field | IO_Field]]'''.
<hr width="50%" />
<big><pre>
IO_Form& operator<<(IO_Field& f);
</pre></big>
Uses the private add() method to add a non-submitter, non-dynamic IO_field'''[[#IO_Field | IO_Field]]'''.
<hr width="50%" />
void* data(unsigned int fieldnumber=0);
</pre></big>
Returns address of the data of "fieldnumber"th, '''[[#IO_Field | IO_Field]]''' in the IO_Form. If "fieldnumber" is zero, then it returns the data of the current '''[[#IO_Field | IO_Field]]'''.
====The index operator====
IO_Field& operator[](unsigned int index);
</pre></big>
Returns the reference of the '''[[#IO_Field| IO_Field]]''', number "fieldnumber-1". First Field has the index 0;
<hr width="50%" />
</blockquote>
The display function work in the following order:
# If IO_CLEAR bit is set in '''how''', then before anything the screen should be be cleared.
# If the field number is 0 (zero) then
## if IO_SHOW_ALL is set in '''how''', then all the fields are displayed in the order they were added
## otherwise either of IO_SHOW_ERROR or IO_SHOW_HELP is set, only their corresponding designated IO_Label will be displayed.
# if the filed field number is not zero, then the IO_Field number "fieldnumber" will be displayed. If the number is larger than the number of fields in the IO_Form then it will be rotated back from the beginning. (i.e. if there are 4 fields in the form and fieldnumber is 5, then filed number 1 will be displayed)
<hr width="50%" />
</pre></big>
If neither of the '''[[#IO_Field | IO_Fields ]]''' is editable, it displays all the '''[[#IO_Field | IO_Fields]]''', then waits for a key entry and then ends the function by returning the key entered.
If the fieldnumber pointer is NULL, it should use a local variable’s address with the value of “0” zero instead.
if If *fieldnumber is (0) zero, then display all the fields before editing the fields and then set *fieldnumber to (1) one.
Start editing from field number *fieldnumbefieldnumber.
Call the edit of each field and depending on the value returned, do the following:
* For '''TAB_KEY ''' and '''DOWN_KEY''', go to next editable '''[[#IO_Field| IO_Field]]''', if this is the last editable '''[[#IO_Field , | IO_Field]]''' then restart from the '''[[#IO_Field | IO_Field ]]''' number one.
* For '''UP_KEY ''' go to the previous editable '''[[#IO_Field| IO_Field]]''', if there is no previous editable '''[[#IO_Field| IO_Field]]''', go to the last editable '''[[#IO_Field | IO_Field]]''' of the ''IO_Form. ('' and continue the search from the last for an editable '''[[#IO_Field | IO_Field in the IO_Form)]]'''.
* for For '''ENTER_KEY ''' do exactly as '''TAB_KEY''', except that if the current '''[[#IO_Field | IO_Field]]''' is a submitter (is tagged to be a submitter when added), in which case terminate the edit function returning the '''ENTER_KEY'''.
* for For any other key, terminate the edit function returning the character which caused the termination.
<hr width="50%" />
''Note that '''data''' is a void pointer; to use it here, you must cast it to a character pointer!''<br />
<big><pre>
IO_Label(const char* str, int row, int col, int len = -1);
</pre></big>
If '''len''' is greater than zero, This constructor will create an IO_Label by allocating len + 1 characters pointed by IO_Field::_data, and then the contents of '''str''' is copied into IO_Field::_data up to '''len''' characters. '''_len''' attribute is set to '''len''';
===Public Methods===
<big><pre>
void Displaydisplay(void);
</pre></big>
'''Display()''' is a direct call to '''io_display()''' function printing '''_data''', at '''getRow()''' and '''getCol()''' up to '''_len''' characters. If '''_len''' is less than zero, then '''_data''' will be printed to the end.
<big><pre>
void Setset(const void* str);
</pre></big>
'''Set()''' will copy the content of '''str''' into '''IO_Field::_data''' up to '''_len''' characters, if '''_len''' is not negative.
<big><pre>
bool Editableeditable(void)const;
</pre></big>
'''Editable()''' returns false!.
<big><pre>
int Editedit(void);
</pre></big>
'''Edit()''', Calls '''Display()''' and returns '''0'''. This method ignores the '''Owner''', IO_Form pointer.
The destructor, delete[]s the '''_data'''. (make sure '''_data''' is casted to char* before deleting.
<big><pre>
IO_Label &operator=(const char* str);
</pre></big>
'''operator=()''', Calls '''Setset()''' and returns itself.
==IO_Edit==
Inherit IO_Field and IO_Frame into a new class called IO_Edit. (Read: Practical Programming Techniques Using C++, pages 94 to 96, ''Multiple Inheritance'' topic)
IO_Edit, encapsulates the '''[[OOP344_Assignment_One#Line_and_Selection_Editor|io_edit() ]]''' function of ciol library when isTextEditor is false. IO_Edit calls the io_edit function to edit a string that is either created dynamically by the IO_Edit itself, or a string that is external and is received through the constructor arguments.
Also IO_Edit gives the user the option of surrounding the editing line with a frame.
</pre></big>
===Constructors and Destructor===
====Constructors====
*'''format''' is a 3 char string that holds the shape of a checked option(i.e. "[X]" or "<@>"),if the format is zero, then depending of the value of '''mode''' being '''Radio''' or '''CheckBox''', frame will be defaulted to '''_RADIOLIST_CHARS''' or '''_CHECKLIST_CHARS''' respectively.
*'''frameChars''' is a string with the characters building the frame.
 
'''Member Variables:'''
*'''char** _items''' is a pointer to an array of character pointers.
*'''int _len''' contains the number of character pointers in _items. In other words, the number of items in the checklist.
*'''int _titlelen''' contains the length of the longest item in the list.
===Public Methods===
int edit(void);
</pre></big>
*This function can change the status for each check item. Use UPKEY and DOWNKEY to select the individual check item, SPACE key to toggle the check status, and other keys to exit the edit mode. This function return returns the last key value.
<big><pre>
int selectedIndex(void);
</pre></big>
*return the index of the first checked item. return -1 if none of them checked.
 
<big><pre>
bool editable()const;
</pre></big>
*always return true.
 
<big><pre>
void set(const void *flags);
</pre></big>
*set the status (checked or unchecked)for each item.
 
<big><pre>
bool& operator[](unsigned int index);
</pre></big>
*return the checked status for the item indexed by parameter index.
 
<big><pre>
int length(void);
</pre></big>
*return the number of items
---incomplete---
void display()const;
</pre></big>
This function displays menu items horizontally or vertically.For vertical menu,
the menu items will be framed.
<big><pre>
int edit(void);
</pre></big>
This function allows users to navigate through menu items by pressing page down
& up keys for vertical menu and right & left keys for horizontal menu. By
pressing space key,current menu item would be selected, our previous selected
menu item would be displayed then deselected.Other keys just terminates the
function and returns the key.
<big><pre>
int selectedIndex(void);
int length(void);
</pre></big>
This function returns length of menu. In other words, it returns number of menu
items.
==IO_TextEdit==
Inherit IO_Field and IO_Frame into a new class called IO_TextEdit. (Read: Practical Programming Techniques Using C++, pages 94 to 96, Multiple Inheritance topic)
IO_TextEdit, uses the io_edit() function of ciol library if the having its isTextEditor flag set to true(1). IO_TextEdit calls the io_edit function repeatedly to edit series of strings that is created dynamically by the IO_TextEdit. If an initial initially a newline -separated ('\n') separated string is provided, IO_TextEdit will split the string into several strings and copy them into dynamically allocated series of strings.
IO_TextEdit will do the edit in a framed multiline text field. Editing begins with the cursor at the top left of the field or from the position the editing was terminated beforelast time.
Each line can be edited using the io_edit. If during the process of editing the string is shifted, make sure all lines are shifted together. If in overstrike mode hitting the enter key goes to next line. Otherwise (in insert mode) it should insert a new line after the current line and if there is any data after the current position, the data should be cut, and pasted to the newly created line. The cursor should stand at the beginning of the new line.
Up and Down arrows should focus the editing on previous and next lines respectfully and if needed, to accommodate this the lines should shift to up and down. However, However if UP and Down keys are hit on the first or last line of data, then the function will terminate returning those values.
Page up and down should scroll the lines in the text field up and down "height-2" times, or better to say, scroll the text a page up or down if possible. if paging is not possible, then the keys are ignored.
Each line in the text can be the maximum of "_IO_TEXT_ALLOCATION_LINE_SIZE" characters, defined in io_def.h
===Constructors===
IO_TextEdit can be created as follows:
int maxLines = -1,const char* frameChars = (const char*)0);</pre></big>
This constructor set the class to dynamically create "series of strings" to be edited by io_edit function in the edit method when needed.The arguments, row and column are top and left coordinates of the text field and width and hieght height are the width and height of the text field.
insertMode is where the insert flag status is kept.
frameChars hold the optional characters to build the frame.
The "single dimension string" representation of the "series of the strings" holding the text will the then be where str argument is pointing to. No dynamic memory is allocated for this.It is the caller program's responsibilty responsibility to accommodate enough space for the data;
maxLines argument will limit the number of the lines in text, unless it is set to -1.
===void set(const void *str);===
splits the newline separated data from the "str" argument into "series of stingsstrings" that are created dynamically to be edited by the io_edit function in the edit method.
===virtual ~IO_TextEdit();===
bool ValidYear(const char* data, IO_Form& F){
bool res = true;
int i = 0; sscanfatoi(data,"%d",&i);
if( i < 1895 || i > 2010){
res = false;
bool ValidRating(const char*data, IO_Form& F){
bool res = true;
double d = -1.0; sscanfatof(data,"%lf", &d);
if( d<0.0 || d>10 ){
res = false;
'''fardad:''' Done, you can now update you working copy and see what I did. You should do the same for all the other classes. It should not take you more than 30 minutes to do your part, just pick a class and write it.
 
==Compiling under linux==
 
If anyone is actually trying to compile under linux, they will notice quickly it fails.
 
To compile in matrix, use:
 
g++ yada.cpp yadoo.cpp -x c ciol.c -lncurses
 
 
If you have many cpp's, you may also do
 
g++ *.cpp -x c ciol.c -lncurses
3
edits

Navigation menu