In our first look at the professor problem, the ProfArray was an array of Professor. There was no interaction between the Professor class and any other class so this worked very well. Once we add the Course class which will contain a pointer to the professor for the course (so changes in the professor can be incorporated into the course), we must redesign our ProfArray. The easiest way to do this is to create an array of RcPointers to Professors. We could also put our Courses into a list as pointers, but in this case changes in courses do not result in changes to other classes so we will not use pointers.
In addition to changes in the content of the arrays, we want to add some functionality to the arrays. If a professor is deleted, we want to find all courses with that professor and change the professor, so we need a way to find each course taught by a professor. We add this function to the course array, and a function to course to find out if it is taught by a given professor. To see the header for the course related classes click here.
The professor list must be capable of storing information about a deleted prof so that this information can be passed to the course list. The information is also used to restore the list in case the course window cancels a delete. DeleteItemAt must be overridden to store the information before the data is deleted. The Professor class needs the function setValue to set values after editing. To see the professor header click here.
To appreciate the reasons for the changes in these classes consider the simple act of changing a professor's name. This will require the name in the course window also change. The EvPaint function for each window scrolls through the arrays and shows the new values, so if a change in the Professor automatically changes the values in courses taught by that professor, then Invalidate will display these changes.
First notice that we store an RcPointer to the professor in our class (see the course header). When we create the course this pointer is retrieved directly from the array of professor pointers ProfArray.
void CourseWindow::cmNewCourse ()
{
// INSERT>> Your code here.
CourseDialogXfer tb;
ArrayIterator next(*_professors);
while(next)
{
char buff[255];
next()->name(buff);
tb._prof.AddString(buff);
next++;
}
tb._prof.Select(0);
tb._number[0]='\0';
if(CourseDialog(&tb,this).Execute()==IDOK)
{
Course c(tb._number,(*_professors)[tb._prof.GetSelIndex()]);
_courses->insertItem(c);
PostMessage(WM_PAINT,0,0);
}
}
| The CourseDialog lists professors in a ComboBox and allows the user to enter a number. The location of a professor in the combobox (tb._prof) corresponds the location in the ProfArray of the professor requested. This is sufficient information to create a new course and insert it into the CourseList. |
The pointer to the professor in a course will be automatically updated when the professor is edited, and the new information displayed when the professor's window is invalidated.
void ProfWindow::cmEditProf ()
{
// INSERT>> Your code here.
int which = _professors->GetSelIndex();
if (which >=0)
{
ProfPtr p =(*_profList)[which];
ProfDlgXfer tb;
strcpy(tb._firstName,p->first().c_str());
strcpy(tb._initial,p->initial().c_str());
strcpy(tb._lastName,p->last().c_str());
strcpy(tb._phone,p->phone().c_str());
strcpy(tb._office,p->office().c_str());
tb._rank.AddString("Assistant");
tb._rank.AddString("Associate");
tb._rank.AddString("Full");
tb._rank.Select(p->rank());
if (ProfDlg(&tb,this).Execute()== IDOK)
{
int rank = tb._rank.GetSelIndex();
char phone[255];
strcpy(phone,"920-465-");
strcat(phone,tb._phone);
(*_profList)[which]->setValues(tb._lastName,tb._firstName,tb._initial,tb._office,phone,rank);
Invalidate();
}
}
else
MessageBox("Must select an item before editing");
}
Notice that the professor's data is set in the existing professor pointer, so that the link between courses and professors is not lost. Unfortunately, deleting a professor leads to much more complicated problems that will be covered next week.