Back to index

fet  5.18.0
Public Member Functions | Public Attributes | Private Member Functions
Rules Class Reference

This class contains all the information regarding the institution: teachers, students, activities, constraints, etc. More...

#include <rules.h>

Collaboration diagram for Rules:
Collaboration graph
[legend]

List of all members.

Public Member Functions

void init ()
 Initializes the rules (empty)
bool computeInternalStructure (QWidget *parent)
 Internal structure initializer.
void kill ()
 Terminator - basically clears the memory for the constraints.
 Rules ()
 ~Rules ()
void setInstitutionName (const QString &newInstitutionName)
void setComments (const QString &newComments)
bool addTeacher (Teacher *teacher)
 Adds a new teacher (if not already in the list).
bool addTeacherFast (Teacher *teacher)
int searchTeacher (const QString &teacherName)
 Returns the index of this teacher in the teachersList, or -1 for inexistent teacher.
bool removeTeacher (const QString &teacherName)
 Removes this teacher and all related activities and constraints.
bool modifyTeacher (const QString &initialTeacherName, const QString &finalTeacherName)
 Modifies (renames) this teacher and takes care of all related activities and constraints.
void sortTeachersAlphabetically ()
 A function to sort the teachers alphabetically.
bool addSubject (Subject *subject)
 Adds a new subject (if not already in the list).
bool addSubjectFast (Subject *subject)
int searchSubject (const QString &subjectName)
 Returns the index of this subject in the subjectsList, or -1 if not found.
bool removeSubject (const QString &subjectName)
 Removes this subject and all related activities and constraints.
bool modifySubject (const QString &initialSubjectName, const QString &finalSubjectName)
 Modifies (renames) this subject and takes care of all related activities and constraints.
void sortSubjectsAlphabetically ()
 A function to sort the subjects alphabetically.
bool addActivityTag (ActivityTag *activityTag)
 Adds a new activity tag to the list of activity tags (if not already in the list).
bool addActivityTagFast (ActivityTag *activityTag)
int searchActivityTag (const QString &activityTagName)
 Returns the index of this activity tag in the activityTagsList, or -1 if not found.
bool removeActivityTag (const QString &activityTagName)
 Removes this activity tag.
bool modifyActivityTag (const QString &initialActivityTagName, const QString &finalActivityTagName)
 Modifies (renames) this activity tag and takes care of all related activities.
void sortActivityTagsAlphabetically ()
 A function to sort the activity tags alphabetically.
StudentsSetsearchStudentsSet (const QString &setName)
 Returns a pointer to the structure containing this student set (year, group or subgroup) or NULL.
StudentsSetsearchAugmentedStudentsSet (const QString &setName)
bool setsShareStudents (const QString &studentsSet1, const QString &studentsSet2)
 True if the students sets contain one common subgroup.
bool addYear (StudentsYear *year)
 Adds a new year of study to the academic structure.
bool addYearFast (StudentsYear *year)
bool removeYear (const QString &yearName)
int searchYear (const QString &yearName)
 Returns -1 if not found or the index of this year in the years list.
int searchAugmentedYear (const QString &yearName)
bool modifyYear (const QString &initialYearName, const QString &finalYearName, int finalNumberOfStudents)
 Modifies this students year (name, number of students) and takes care of all related activities and constraints.
void sortYearsAlphabetically ()
 A function to sort the years alphabetically.
bool addGroup (const QString &yearName, StudentsGroup *group)
 Adds a new group in a certain year of study to the academic structure.
bool addGroupFast (StudentsYear *year, StudentsGroup *group)
bool removeGroup (const QString &yearName, const QString &groupName)
int searchGroup (const QString &yearName, const QString &groupName)
 Returns -1 if not found or the index of this group in the groups list of this year.
int searchAugmentedGroup (const QString &yearName, const QString &groupName)
bool modifyGroup (const QString &yearName, const QString &initialGroupName, const QString &finalGroupName, int finalNumberOfStudents)
 Modifies this students group (name, number of students) and takes care of all related activities and constraints.
void sortGroupsAlphabetically (const QString &yearName)
 A function to sort the groups of this year alphabetically.
bool addSubgroup (const QString &yearName, const QString &groupName, StudentsSubgroup *subgroup)
 Adds a new subgroup to a certain group in a certain year of study to the academic structure.
bool addSubgroupFast (StudentsYear *year, StudentsGroup *group, StudentsSubgroup *subgroup)
bool removeSubgroup (const QString &yearName, const QString &groupName, const QString &subgroupName)
int searchSubgroup (const QString &yearName, const QString &groupName, const QString &subgroupName)
 Returns -1 if not found or the index of the subgroup in the list of subgroups of this group.
int searchAugmentedSubgroup (const QString &yearName, const QString &groupName, const QString &subgroupName)
bool modifySubgroup (const QString &yearName, const QString &groupName, const QString &initialSubgroupName, const QString &finalSubgroupName, int finalNumberOfStudents)
 Modifies this students subgroup (name, number of students) and takes care of all related activities and constraints.
void sortSubgroupsAlphabetically (const QString &yearName, const QString &groupName)
 A function to sort the subgroups of this group alphabetically.
bool addSimpleActivity (QWidget *parent, int _id, int _activityGroupId, const QStringList &_teachersNames, const QString &_subjectName, const QStringList &_activityTagsNames, const QStringList &_studentsNames, int _duration, int _totalDuration, bool _active, bool _computeNTotalStudents, int _nTotalStudents)
 Adds a new indivisible activity (not split) to the list of activities.
bool addSimpleActivityRulesFast (QWidget *parent, int _id, int _activityGroupId, const QStringList &_teachersNames, const QString &_subjectName, const QStringList &_activityTagsNames, const QStringList &_studentsNames, int _duration, int _totalDuration, bool _active, bool _computeNTotalStudents, int _nTotalStudents, int _computedNumberOfStudents)
bool addSplitActivity (QWidget *parent, int _firstActivityId, int _activityGroupId, const QStringList &_teachersNames, const QString &_subjectName, const QStringList &_activityTagsNames, const QStringList &_studentsNames, int _nSplits, int _totalDuration, int _durations[], bool _active[], int _minDayDistance, double _weightPercentage, bool _consecutiveIfSameDay, bool _computeNTotalStudents, int _nTotalStudents)
 Adds a new split activity to the list of activities.
void removeActivity (int _id)
 Removes only the activity with this id.
void removeActivity (int _id, int _activityGroupId)
 If _activityGroupId==0, then this is a non-split activity (if >0, then this is a single sub-activity from a split activity.
void modifyActivity (int _id, int _activityGroupId, const QStringList &_teachersNames, const QString &_subjectName, const QStringList &_activityTagsNames, const QStringList &_studentsNames, int _nSplits, int _totalDuration, int _durations[], bool _active[], bool _computeNTotalStudents, int nTotalStudents)
 A function to modify the information of a certain activity.
void modifySubactivity (int _id, int _activityGroupId, const QStringList &_teachersNames, const QString &_subjectName, const QStringList &_activityTagsNames, const QStringList &_studentsNames, int _duration, bool _active, bool _computeNTotalStudents, int nTotalStudents)
bool addRoom (Room *rm)
 Adds a new room (already allocated).
bool addRoomFast (Room *rm)
int searchRoom (const QString &roomName)
 Returns -1 if not found or the index in the rooms list if found.
bool removeRoom (QWidget *parent, const QString &roomName)
 Removes the room with this name.
bool modifyRoom (const QString &initialRoomName, const QString &finalRoomName, const QString &building, int capacity)
 Modifies this room and takes care of all related constraints.
void sortRoomsAlphabetically ()
 A function to sort the room alphabetically, by name.
bool addBuilding (Building *rm)
 Adds a new building (already allocated).
bool addBuildingFast (Building *rm)
int searchBuilding (const QString &buildingName)
 Returns -1 if not found or the index in the buildings list if found.
bool removeBuilding (const QString &buildingName)
 Removes the building with this name.
bool modifyBuilding (const QString &initialBuildingName, const QString &finalBuildingName)
 Modifies this building and takes care of all related constraints.
void sortBuildingsAlphabetically ()
 A function to sort the buildings alphabetically, by name.
bool addTimeConstraint (TimeConstraint *ctr)
 Adds a new time constraint (already allocated).
bool removeTimeConstraint (TimeConstraint *ctr)
 Removes this time constraint.
bool addSpaceConstraint (SpaceConstraint *ctr)
 Adds a new space constraint (already allocated).
bool removeSpaceConstraint (SpaceConstraint *ctr)
 Removes this space constraint.
bool read (QWidget *parent, const QString &filename, bool commandLine=false, QString commandLineDirectory=QString())
 Reads the rules from the xml input file "filename".
bool write (QWidget *parent, const QString &filename)
 Write the rules to the xml input file "inputfile".
int activateTeacher (const QString &teacherName)
int activateStudents (const QString &studentsName)
int activateSubject (const QString &subjectName)
int activateActivityTag (const QString &activityTagName)
int deactivateTeacher (const QString &teacherName)
int deactivateStudents (const QString &studentsName)
int deactivateSubject (const QString &subjectName)
int deactivateActivityTag (const QString &activityTagName)

Public Attributes

bool modified
QString institutionName
 The name of the institution.
QString comments
 The comments.
int nHoursPerDay
 The number of hours per day.
int nDaysPerWeek
 The number of days per week.
QString daysOfTheWeek [MAX_DAYS_PER_WEEK]
 The days of the week (names)
QString hoursOfTheDay [MAX_HOURS_PER_DAY+1]
 The hours of the day (names).
int nHoursPerWeek
 The number of hours per week.
TeachersList teachersList
 The list of teachers.
SubjectsList subjectsList
 The list of subjects.
ActivityTagsList activityTagsList
 The list of activity tags.
StudentsYearsList yearsList
 The list of students (groups and subgroups included).
ActivitiesList activitiesList
 The list of activities.
RoomsList roomsList
 The list of rooms.
BuildingsList buildingsList
 The list of buildings.
TimeConstraintsList timeConstraintsList
 The list of time constraints.
SpaceConstraintsList spaceConstraintsList
 The list of space constraints.
int nInternalTeachers
Matrix1D< Teacher * > internalTeachersList
int nInternalSubjects
Matrix1D< Subject * > internalSubjectsList
int nInternalActivityTags
Matrix1D< ActivityTag * > internalActivityTagsList
int nInternalSubgroups
Matrix1D< StudentsSubgroup * > internalSubgroupsList
StudentsGroupsList internalGroupsList
StudentsYearsList augmentedYearsList
int nInternalActivities
 Here will be only the active activities.
Matrix1D< ActivityinternalActivitiesList
QSet< int > inactiveActivities
Matrix1D< QList< int > > activitiesForSubject
int nInternalRooms
Matrix1D< Room * > internalRoomsList
int nInternalBuildings
Matrix1D< Building * > internalBuildingsList
int nInternalTimeConstraints
Matrix1D< TimeConstraint * > internalTimeConstraintsList
int nInternalSpaceConstraints
Matrix1D< SpaceConstraint * > internalSpaceConstraintsList
bool initialized
 True if the rules have been initialized in some way (new or loaded).
bool internalStructureComputed
 True if the internal structure was computed.

Private Member Functions

TimeConstraintreadBasicCompulsoryTime (const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadTeacherNotAvailable (QWidget *parent, const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadTeacherNotAvailableTimes (QWidget *parent, const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadTeacherMaxDaysPerWeek (QWidget *parent, const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadTeachersMaxDaysPerWeek (QWidget *parent, const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadTeacherMinDaysPerWeek (QWidget *parent, const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadTeachersMinDaysPerWeek (QWidget *parent, const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadTeacherIntervalMaxDaysPerWeek (QWidget *parent, const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadTeachersIntervalMaxDaysPerWeek (QWidget *parent, const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadStudentsSetIntervalMaxDaysPerWeek (QWidget *parent, const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadStudentsIntervalMaxDaysPerWeek (QWidget *parent, const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadStudentsSetNotAvailable (QWidget *parent, const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadStudentsSetNotAvailableTimes (QWidget *parent, const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadMinNDaysBetweenActivities (QWidget *parent, const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadMinDaysBetweenActivities (QWidget *parent, const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadMaxDaysBetweenActivities (const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadMinGapsBetweenActivities (const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadActivitiesNotOverlapping (const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadActivitiesSameStartingTime (const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadActivitiesSameStartingHour (const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadActivitiesSameStartingDay (const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadTeachersMaxHoursDaily (const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadTeacherMaxHoursDaily (const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadTeachersMaxHoursContinuously (const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadTeacherMaxHoursContinuously (const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadTeacherActivityTagMaxHoursContinuously (const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadTeachersActivityTagMaxHoursContinuously (const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadTeacherActivityTagMaxHoursDaily (const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadTeachersActivityTagMaxHoursDaily (const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadTeachersMinHoursDaily (QWidget *parent, const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadTeacherMinHoursDaily (QWidget *parent, const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadStudentsMaxHoursDaily (const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadStudentsSetMaxHoursDaily (const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadStudentsMaxHoursContinuously (const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadStudentsSetMaxHoursContinuously (const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadStudentsSetActivityTagMaxHoursContinuously (const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadStudentsActivityTagMaxHoursContinuously (const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadStudentsSetActivityTagMaxHoursDaily (const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadStudentsActivityTagMaxHoursDaily (const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadStudentsMinHoursDaily (QWidget *parent, const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadStudentsSetMinHoursDaily (QWidget *parent, const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadActivityPreferredTime (QWidget *parent, const QDomElement &elem3, FakeString &xmlReadingLog, bool &reportUnspecifiedPermanentlyLockedTime, bool &reportUnspecifiedDayOrHourPreferredStartingTime)
TimeConstraintreadActivityPreferredStartingTime (QWidget *parent, const QDomElement &elem3, FakeString &xmlReadingLog, bool &reportUnspecifiedPermanentlyLockedTime, bool &reportUnspecifiedDayOrHourPreferredStartingTime)
TimeConstraintreadActivityEndsStudentsDay (const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadActivitiesEndStudentsDay (const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintread2ActivitiesConsecutive (const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintread2ActivitiesGrouped (const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintread3ActivitiesGrouped (const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintread2ActivitiesOrdered (const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadTwoActivitiesConsecutive (const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadTwoActivitiesGrouped (const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadThreeActivitiesGrouped (const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadTwoActivitiesOrdered (const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadActivityPreferredTimes (QWidget *parent, const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadActivityPreferredTimeSlots (QWidget *parent, const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadActivityPreferredStartingTimes (QWidget *parent, const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadBreak (QWidget *parent, const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadBreakTimes (QWidget *parent, const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadTeachersNoGaps (const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadTeachersMaxGapsPerWeek (const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadTeacherMaxGapsPerWeek (const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadTeachersMaxGapsPerDay (const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadTeacherMaxGapsPerDay (const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadStudentsNoGaps (const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadStudentsSetNoGaps (const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadStudentsMaxGapsPerWeek (const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadStudentsSetMaxGapsPerWeek (const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadStudentsMaxGapsPerDay (const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadStudentsSetMaxGapsPerDay (const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadStudentsEarly (const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadStudentsEarlyMaxBeginningsAtSecondHour (const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadStudentsSetEarly (const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadStudentsSetEarlyMaxBeginningsAtSecondHour (const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadActivitiesPreferredTimes (QWidget *parent, const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadActivitiesPreferredTimeSlots (QWidget *parent, const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadActivitiesPreferredStartingTimes (QWidget *parent, const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadSubactivitiesPreferredTimeSlots (QWidget *parent, const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadSubactivitiesPreferredStartingTimes (QWidget *parent, const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadActivitiesOccupyMaxTimeSlotsFromSelection (QWidget *parent, const QDomElement &elem3, FakeString &xmlReadingLog)
TimeConstraintreadActivitiesMaxSimultaneousInSelectedTimeSlots (QWidget *parent, const QDomElement &elem3, FakeString &xmlReadingLog)
SpaceConstraintreadBasicCompulsorySpace (const QDomElement &elem3, FakeString &xmlReadingLog)
 space constraints reading routines
SpaceConstraintreadRoomNotAvailable (QWidget *parent, const QDomElement &elem3, FakeString &xmlReadingLog)
SpaceConstraintreadRoomNotAvailableTimes (QWidget *parent, const QDomElement &elem3, FakeString &xmlReadingLog)
SpaceConstraintreadActivityPreferredRoom (QWidget *parent, const QDomElement &elem3, FakeString &xmlReadingLog, bool &reportUnspecifiedPermanentlyLockedSpace)
SpaceConstraintreadActivityPreferredRooms (const QDomElement &elem3, FakeString &xmlReadingLog)
SpaceConstraintreadSubjectPreferredRoom (const QDomElement &elem3, FakeString &xmlReadingLog)
SpaceConstraintreadSubjectPreferredRooms (const QDomElement &elem3, FakeString &xmlReadingLog)
SpaceConstraintreadSubjectSubjectTagPreferredRoom (const QDomElement &elem3, FakeString &xmlReadingLog)
SpaceConstraintreadSubjectSubjectTagPreferredRooms (const QDomElement &elem3, FakeString &xmlReadingLog)
SpaceConstraintreadSubjectActivityTagPreferredRoom (const QDomElement &elem3, FakeString &xmlReadingLog)
SpaceConstraintreadSubjectActivityTagPreferredRooms (const QDomElement &elem3, FakeString &xmlReadingLog)
SpaceConstraintreadActivityTagPreferredRoom (const QDomElement &elem3, FakeString &xmlReadingLog)
SpaceConstraintreadActivityTagPreferredRooms (const QDomElement &elem3, FakeString &xmlReadingLog)
SpaceConstraintreadStudentsSetHomeRoom (const QDomElement &elem3, FakeString &xmlReadingLog)
SpaceConstraintreadStudentsSetHomeRooms (const QDomElement &elem3, FakeString &xmlReadingLog)
SpaceConstraintreadTeacherHomeRoom (const QDomElement &elem3, FakeString &xmlReadingLog)
SpaceConstraintreadTeacherHomeRooms (const QDomElement &elem3, FakeString &xmlReadingLog)
SpaceConstraintreadTeacherMaxBuildingChangesPerDay (const QDomElement &elem3, FakeString &xmlReadingLog)
SpaceConstraintreadTeachersMaxBuildingChangesPerDay (const QDomElement &elem3, FakeString &xmlReadingLog)
SpaceConstraintreadTeacherMaxBuildingChangesPerWeek (const QDomElement &elem3, FakeString &xmlReadingLog)
SpaceConstraintreadTeachersMaxBuildingChangesPerWeek (const QDomElement &elem3, FakeString &xmlReadingLog)
SpaceConstraintreadTeacherMinGapsBetweenBuildingChanges (const QDomElement &elem3, FakeString &xmlReadingLog)
SpaceConstraintreadTeachersMinGapsBetweenBuildingChanges (const QDomElement &elem3, FakeString &xmlReadingLog)
SpaceConstraintreadStudentsSetMaxBuildingChangesPerDay (const QDomElement &elem3, FakeString &xmlReadingLog)
SpaceConstraintreadStudentsMaxBuildingChangesPerDay (const QDomElement &elem3, FakeString &xmlReadingLog)
SpaceConstraintreadStudentsSetMaxBuildingChangesPerWeek (const QDomElement &elem3, FakeString &xmlReadingLog)
SpaceConstraintreadStudentsMaxBuildingChangesPerWeek (const QDomElement &elem3, FakeString &xmlReadingLog)
SpaceConstraintreadStudentsSetMinGapsBetweenBuildingChanges (const QDomElement &elem3, FakeString &xmlReadingLog)
SpaceConstraintreadStudentsMinGapsBetweenBuildingChanges (const QDomElement &elem3, FakeString &xmlReadingLog)
SpaceConstraintreadActivitiesOccupyMaxDifferentRooms (const QDomElement &elem3, FakeString &xmlReadingLog)

Detailed Description

This class contains all the information regarding the institution: teachers, students, activities, constraints, etc.

Definition at line 68 of file rules.h.


Constructor & Destructor Documentation

Definition at line 816 of file rules.cpp.

{
       this->initialized=false;
       this->modified=false;
}

Definition at line 822 of file rules.cpp.

{
       if(this->initialized)
              this->kill();
}

Member Function Documentation

int Rules::activateActivityTag ( const QString &  activityTagName)

Definition at line 7438 of file rules.cpp.

{
       int count=0;
       for(int i=0; i<this->activitiesList.size(); i++){
              Activity* act=this->activitiesList[i];
              if(act->activityTagsNames.contains(activityTagName)){
                     if(!act->active)
                            count++;
                     act->active=true;
              }
       }

       this->internalStructureComputed=false;
       setRulesModifiedAndOtherThings(this);
       
       return count;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int Rules::activateStudents ( const QString &  studentsName)

Definition at line 7377 of file rules.cpp.

{
       QSet<QString> allSets;
       
       StudentsSet* set=this->searchStudentsSet(studentsName);
       if(set->type==STUDENTS_SUBGROUP)
              allSets.insert(studentsName);
       else if(set->type==STUDENTS_GROUP){
              allSets.insert(studentsName);
              StudentsGroup* g=(StudentsGroup*)set;
              foreach(StudentsSubgroup* s, g->subgroupsList)
                     allSets.insert(s->name);
       }
       else if(set->type==STUDENTS_YEAR){
              allSets.insert(studentsName);
              StudentsYear* y=(StudentsYear*)set;
              foreach(StudentsGroup* g, y->groupsList){
                     allSets.insert(g->name);
                     foreach(StudentsSubgroup* s, g->subgroupsList)
                            allSets.insert(s->name);
              }
       }

       int count=0;
       for(int i=0; i<this->activitiesList.size(); i++){
              Activity* act=this->activitiesList[i];
              if(!act->active){
                     foreach(QString set, act->studentsNames){
                            if(allSets.contains(set)){
                                   count++;
                                   act->active=true;
                                   break;
                            }
                     }
              }
       }

       this->internalStructureComputed=false;
       setRulesModifiedAndOtherThings(this);
       
       return count;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int Rules::activateSubject ( const QString &  subjectName)

Definition at line 7420 of file rules.cpp.

{
       int count=0;
       for(int i=0; i<this->activitiesList.size(); i++){
              Activity* act=this->activitiesList[i];
              if(act->subjectName==subjectName){
                     if(!act->active)
                            count++;
                     act->active=true;
              }
       }

       this->internalStructureComputed=false;
       setRulesModifiedAndOtherThings(this);
       
       return count;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int Rules::activateTeacher ( const QString &  teacherName)

Definition at line 7359 of file rules.cpp.

{
       int count=0;
       for(int i=0; i<this->activitiesList.size(); i++){
              Activity* act=this->activitiesList[i];
              if(act->searchTeacher(teacherName)){
                     if(!act->active)
                            count++;
                     act->active=true;
              }
       }

       this->internalStructureComputed=false;
       setRulesModifiedAndOtherThings(this);
       
       return count;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool Rules::addActivityTag ( ActivityTag activityTag)

Adds a new activity tag to the list of activity tags (if not already in the list).

Returns false/true (unsuccessful/successful).

Definition at line 1739 of file rules.cpp.

{
       for(int i=0; i<this->activityTagsList.size(); i++){
              ActivityTag* sbt=this->activityTagsList[i];

              if(sbt->name==activityTag->name)
                     return false;
       }

       this->internalStructureComputed=false;
       setRulesModifiedAndOtherThings(this);

       teachers_schedule_ready=false;
       students_schedule_ready=false;
       rooms_schedule_ready=false;

       this->activityTagsList << activityTag;
       return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool Rules::addActivityTagFast ( ActivityTag activityTag)

Definition at line 1759 of file rules.cpp.

Here is the call graph for this function:

bool Rules::addBuilding ( Building rm)

Adds a new building (already allocated).

Returns true on success, false for already existing buildings (same name).

Definition at line 5014 of file rules.cpp.

{
       if(this->searchBuilding(bu->name) >= 0)
              return false;
       this->buildingsList << bu; //append
       this->internalStructureComputed=false;
       setRulesModifiedAndOtherThings(this);

       teachers_schedule_ready=false;
       students_schedule_ready=false;
       rooms_schedule_ready=false;

       return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 5029 of file rules.cpp.

Here is the call graph for this function:

bool Rules::addGroup ( const QString &  yearName,
StudentsGroup group 
)

Adds a new group in a certain year of study to the academic structure.

Definition at line 2747 of file rules.cpp.

{
       StudentsYear* sty=NULL;
       for(int i=0; i<this->yearsList.size(); i++){
              sty=yearsList[i];
              if(sty->name==yearName)
                     break;
       }
       assert(sty);
       
       for(int i=0; i<sty->groupsList.size(); i++){
              StudentsGroup* stg=sty->groupsList[i];
              if(stg->name==group->name)
                     return false;
       }
       
       sty->groupsList << group; //append

       /*
       foreach(StudentsYear* y, yearsList)
              foreach(StudentsGroup* g, y->groupsList)
                     if(g->name==group->name)
                            g->numberOfStudents=group->numberOfStudents;*/

       this->internalStructureComputed=false;
       setRulesModifiedAndOtherThings(this);
       return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool Rules::addGroupFast ( StudentsYear year,
StudentsGroup group 
)

Definition at line 2776 of file rules.cpp.

{
       year->groupsList << group; //append

       this->internalStructureComputed=false;
       setRulesModifiedAndOtherThings(this);
       return true;
}

Here is the call graph for this function:

bool Rules::addRoom ( Room rm)

Adds a new room (already allocated).

Returns true on success, false for already existing rooms (same name).

Definition at line 4606 of file rules.cpp.

{
       if(this->searchRoom(rm->name) >= 0)
              return false;
       this->roomsList << rm; //append
       this->internalStructureComputed=false;
       setRulesModifiedAndOtherThings(this);

       teachers_schedule_ready=false;
       students_schedule_ready=false;
       rooms_schedule_ready=false;

       return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool Rules::addRoomFast ( Room rm)

Definition at line 4621 of file rules.cpp.

Here is the call graph for this function:

bool Rules::addSimpleActivity ( QWidget *  parent,
int  _id,
int  _activityGroupId,
const QStringList &  _teachersNames,
const QString &  _subjectName,
const QStringList &  _activityTagsNames,
const QStringList &  _studentsNames,
int  _duration,
int  _totalDuration,
bool  _active,
bool  _computeNTotalStudents,
int  _nTotalStudents 
)

Adds a new indivisible activity (not split) to the list of activities.

(It can add a subactivity of a split activity) Returns true if successful or false if the maximum number of activities was reached.

Definition at line 3711 of file rules.cpp.

{
       //check for duplicates - idea and code by Volker Dirr
       int t=QStringList(_teachersNames).removeDuplicates();
       if(t>0)
              QMessageBox::warning(parent, tr("FET warning"), tr("Activity with Id=%1 contains %2 duplicate teachers - please correct that")
               .arg(_id).arg(t));

       t=QStringList(_studentsNames).removeDuplicates();
       if(t>0)
              QMessageBox::warning(parent, tr("FET warning"), tr("Activity with Id=%1 contains %2 duplicate students sets - please correct that")
               .arg(_id).arg(t));

       t=QStringList(_activityTagsNames).removeDuplicates();
       if(t>0)
              QMessageBox::warning(parent, tr("FET warning"), tr("Activity with Id=%1 contains %2 duplicate activity tags - please correct that")
               .arg(_id).arg(t));

       Activity *act=new Activity(*this, _id, _activityGroupId, _teachersNames, _subjectName, _activityTagsNames,
              _studentsNames, _duration, _totalDuration, _active, _computeNTotalStudents, _nTotalStudents);

       this->activitiesList << act; //append

       this->internalStructureComputed=false;
       setRulesModifiedAndOtherThings(this);

       return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool Rules::addSimpleActivityRulesFast ( QWidget *  parent,
int  _id,
int  _activityGroupId,
const QStringList &  _teachersNames,
const QString &  _subjectName,
const QStringList &  _activityTagsNames,
const QStringList &  _studentsNames,
int  _duration,
int  _totalDuration,
bool  _active,
bool  _computeNTotalStudents,
int  _nTotalStudents,
int  _computedNumberOfStudents 
)

Definition at line 3752 of file rules.cpp.

{
       //check for duplicates - idea and code by Volker Dirr
       int t=QStringList(_teachersNames).removeDuplicates();
       if(t>0)
              QMessageBox::warning(parent, tr("FET warning"), tr("Activity with Id=%1 contains %2 duplicate teachers - please correct that")
               .arg(_id).arg(t));

       t=QStringList(_studentsNames).removeDuplicates();
       if(t>0)
              QMessageBox::warning(parent, tr("FET warning"), tr("Activity with Id=%1 contains %2 duplicate students sets - please correct that")
               .arg(_id).arg(t));

       t=QStringList(_activityTagsNames).removeDuplicates();
       if(t>0)
              QMessageBox::warning(parent, tr("FET warning"), tr("Activity with Id=%1 contains %2 duplicate activity tags - please correct that")
               .arg(_id).arg(t));

       Activity *act=new Activity(*this, _id, _activityGroupId, _teachersNames, _subjectName, _activityTagsNames,
              _studentsNames, _duration, _totalDuration, _active, _computeNTotalStudents, _nTotalStudents, _computedNumberOfStudents);

       this->activitiesList << act; //append

       this->internalStructureComputed=false;
       setRulesModifiedAndOtherThings(this);

       return true;
}

Here is the call graph for this function:

Adds a new space constraint (already allocated).

Returns true on success, false for already existing constraints.

Definition at line 5227 of file rules.cpp.

{
       bool ok=true;

       //TODO: check if this constraint is already added...(if any possibility of duplicates)
       if(ctr->type==CONSTRAINT_ACTIVITY_PREFERRED_ROOM){
              int i;
              for(i=0; i<this->spaceConstraintsList.size(); i++){
                     SpaceConstraint* ctr2=this->spaceConstraintsList[i];
                     if(ctr2->type==CONSTRAINT_ACTIVITY_PREFERRED_ROOM)
                            if(
                             *((ConstraintActivityPreferredRoom*)ctr2)
                             ==
                             *((ConstraintActivityPreferredRoom*)ctr)
                            )
                                   break;
              }
              
              if(i<this->spaceConstraintsList.size())
                     ok=false;
       }
/*     else if(ctr->type==CONSTRAINT_ROOM_NOT_AVAILABLE_TIMES){
              int i;
              ConstraintRoomNotAvailableTimes* c=(ConstraintRoomNotAvailableTimes*)ctr;
              for(i=0; i<this->spaceConstraintsList.size(); i++){
                     SpaceConstraint* ctr2=this->spaceConstraintsList[i];
                     if(ctr2->type==CONSTRAINT_ROOM_NOT_AVAILABLE_TIMES){
                            ConstraintRoomNotAvailableTimes* c2=(ConstraintRoomNotAvailableTimes*)ctr2;                       
                            if(c->room==c2->room)
                                   break;
                     }
              }
              
              if(i<this->spaceConstraintsList.size())
                     ok=false;
       }*/
       else if(ctr->type==CONSTRAINT_BASIC_COMPULSORY_SPACE){
              int i;
              for(i=0; i<this->spaceConstraintsList.size(); i++){
                     SpaceConstraint* ctr2=this->spaceConstraintsList[i];
                     if(ctr2->type==CONSTRAINT_BASIC_COMPULSORY_SPACE)
                            break;
              }
                            
              if(i<this->spaceConstraintsList.size())
                     ok=false;
       }

       if(ok){
              this->spaceConstraintsList << ctr; //append
              this->internalStructureComputed=false;
              setRulesModifiedAndOtherThings(this);
              return true;
       }
       else
              return false;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool Rules::addSplitActivity ( QWidget *  parent,
int  _firstActivityId,
int  _activityGroupId,
const QStringList &  _teachersNames,
const QString &  _subjectName,
const QStringList &  _activityTagsNames,
const QStringList &  _studentsNames,
int  _nSplits,
int  _totalDuration,
int  _durations[],
bool  _active[],
int  _minDayDistance,
double  _weightPercentage,
bool  _consecutiveIfSameDay,
bool  _computeNTotalStudents,
int  _nTotalStudents 
)

Adds a new split activity to the list of activities.

Returns true if successful or false if the maximum number of activities was reached. If _minDayDistance>0, there will automatically added a compulsory ConstraintMinDaysBetweenActivities.

Definition at line 3794 of file rules.cpp.

{
       //check for duplicates - idea and code by Volker Dirr
       int t=QStringList(_teachersNames).removeDuplicates();
       if(t>0)
              QMessageBox::warning(parent, tr("FET warning"), tr("Activities with group_Id=%1 contain %2 duplicate teachers - please correct that")
               .arg(_activityGroupId).arg(t));

       t=QStringList(_studentsNames).removeDuplicates();
       if(t>0)
              QMessageBox::warning(parent, tr("FET warning"), tr("Activities with group_Id=%1 contain %2 duplicate students sets - please correct that")
               .arg(_activityGroupId).arg(t));

       t=QStringList(_activityTagsNames).removeDuplicates();
       if(t>0)
              QMessageBox::warning(parent, tr("FET warning"), tr("Activities with group_Id=%1 contain %2 duplicate activity tags - please correct that")
               .arg(_activityGroupId).arg(t));

       assert(_firstActivityId==_activityGroupId);

       QList<int> acts;

       acts.clear();
       for(int i=0; i<_nSplits; i++){
              Activity *act;
              if(i==0)
                     act=new Activity(*this, _firstActivityId+i, _activityGroupId,
                            _teachersNames, _subjectName, _activityTagsNames, _studentsNames,
                            _durations[i], _totalDuration, _active[i], _computeNTotalStudents, _nTotalStudents);
              else
                     act=new Activity(*this, _firstActivityId+i, _activityGroupId,
                            _teachersNames, _subjectName, _activityTagsNames, _studentsNames,
                            _durations[i], _totalDuration, _active[i], _computeNTotalStudents, _nTotalStudents);

              this->activitiesList << act; //append

              acts.append(_firstActivityId+i);
       }

       if(_minDayDistance>0){
              TimeConstraint *constr=new ConstraintMinDaysBetweenActivities(_weightPercentage, _consecutiveIfSameDay, _nSplits, acts, _minDayDistance);
              bool tmp=this->addTimeConstraint(constr);
              assert(tmp);
       }

       this->internalStructureComputed=false;
       setRulesModifiedAndOtherThings(this);

       return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool Rules::addSubgroup ( const QString &  yearName,
const QString &  groupName,
StudentsSubgroup subgroup 
)

Adds a new subgroup to a certain group in a certain year of study to the academic structure.

Definition at line 3245 of file rules.cpp.

{
       StudentsYear* sty=this->yearsList.at(this->searchYear(yearName));
       assert(sty);
       StudentsGroup* stg=sty->groupsList.at(this->searchGroup(yearName, groupName));
       assert(stg);


       for(int i=0; i<stg->subgroupsList.size(); i++){
              StudentsSubgroup* sts=stg->subgroupsList[i];
              if(sts->name==subgroup->name)
                     return false;
       }
       
       stg->subgroupsList << subgroup; //append

       /*
       foreach(StudentsYear* y, yearsList)
              foreach(StudentsGroup* g, y->groupsList)
                     foreach(StudentsSubgroup* s, g->subgroupsList)
                            if(s->name==subgroup->name)
                                   s->numberOfStudents=subgroup->numberOfStudents;*/

       this->internalStructureComputed=false;
       setRulesModifiedAndOtherThings(this);
       return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool Rules::addSubgroupFast ( StudentsYear year,
StudentsGroup group,
StudentsSubgroup subgroup 
)

Definition at line 3273 of file rules.cpp.

{
       Q_UNUSED(year);

       group->subgroupsList << subgroup; //append

       this->internalStructureComputed=false;
       setRulesModifiedAndOtherThings(this);
       return true;
}

Here is the call graph for this function:

bool Rules::addSubject ( Subject subject)

Adds a new subject (if not already in the list).

Returns false/true (unsuccessful/successful).

Definition at line 1437 of file rules.cpp.

{
       for(int i=0; i<this->subjectsList.size(); i++){
              Subject* sbj=this->subjectsList[i];       
              if(sbj->name==subject->name)
                     return false;
       }
       
       this->internalStructureComputed=false;
       setRulesModifiedAndOtherThings(this);

       teachers_schedule_ready=false;
       students_schedule_ready=false;
       rooms_schedule_ready=false;

       this->subjectsList << subject;
       return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool Rules::addSubjectFast ( Subject subject)

Definition at line 1456 of file rules.cpp.

Here is the call graph for this function:

bool Rules::addTeacher ( Teacher teacher)

Adds a new teacher (if not already in the list).

Returns false/true (unsuccessful/successful).

Definition at line 842 of file rules.cpp.

{
       for(int i=0; i<this->teachersList.size(); i++){
              Teacher* tch=this->teachersList[i];
              if(tch->name==teacher->name)
                     return false;
       }
       
       this->internalStructureComputed=false;
       setRulesModifiedAndOtherThings(this);

       teachers_schedule_ready=false;
       students_schedule_ready=false;
       rooms_schedule_ready=false;

       this->teachersList.append(teacher);
       return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool Rules::addTeacherFast ( Teacher teacher)

Definition at line 861 of file rules.cpp.

Here is the call graph for this function:

Adds a new time constraint (already allocated).

Returns true on success, false for already existing constraints.

Definition at line 5104 of file rules.cpp.

{
       bool ok=true;

       //TODO: improve this

       //check if this constraint is already added, for ConstraintActivityPreferredStartingTime
       if(ctr->type==CONSTRAINT_ACTIVITY_PREFERRED_STARTING_TIME){
              int i;
              for(i=0; i<this->timeConstraintsList.size(); i++){
                     TimeConstraint* ctr2=this->timeConstraintsList[i];
                     if(ctr2->type==CONSTRAINT_ACTIVITY_PREFERRED_STARTING_TIME) 
                            if(
                             *((ConstraintActivityPreferredStartingTime*)ctr2)
                             ==
                             *((ConstraintActivityPreferredStartingTime*)ctr)
                            )
                                   break;
              }
                            
              if(i<this->timeConstraintsList.size())
                     ok=false;
       }

       //check if this constraint is already added, for ConstraintMinDaysBetweenActivities
       else if(ctr->type==CONSTRAINT_MIN_DAYS_BETWEEN_ACTIVITIES){
              int i;
              for(i=0; i<this->timeConstraintsList.size(); i++){
                     TimeConstraint* ctr2=this->timeConstraintsList[i];
                     if(ctr2->type==CONSTRAINT_MIN_DAYS_BETWEEN_ACTIVITIES)
                            if(
                             *((ConstraintMinDaysBetweenActivities*)ctr2)
                             ==
                             *((ConstraintMinDaysBetweenActivities*)ctr)
                             )
                                   break;
              }

              if(i<this->timeConstraintsList.size())
                     ok=false;
       }
       
       else if(ctr->type==CONSTRAINT_STUDENTS_SET_NOT_AVAILABLE_TIMES){
              int i;
              ConstraintStudentsSetNotAvailableTimes* ssna=(ConstraintStudentsSetNotAvailableTimes*)ctr;
              for(i=0; i<this->timeConstraintsList.size(); i++){
                     TimeConstraint* ctr2=this->timeConstraintsList[i];
                     if(ctr2->type==CONSTRAINT_STUDENTS_SET_NOT_AVAILABLE_TIMES) {
                            ConstraintStudentsSetNotAvailableTimes* ssna2=(ConstraintStudentsSetNotAvailableTimes*)ctr2;
                            if(ssna->students==ssna2->students)
                                   break;
                     }
              }
                            
              if(i<this->timeConstraintsList.size())
                     ok=false;
       }
       
       else if(ctr->type==CONSTRAINT_TEACHER_NOT_AVAILABLE_TIMES){
              int i;
              ConstraintTeacherNotAvailableTimes* tna=(ConstraintTeacherNotAvailableTimes*)ctr;
              for(i=0; i<this->timeConstraintsList.size(); i++){
                     TimeConstraint* ctr2=this->timeConstraintsList[i];
                     if(ctr2->type==CONSTRAINT_TEACHER_NOT_AVAILABLE_TIMES) {
                            ConstraintTeacherNotAvailableTimes* tna2=(ConstraintTeacherNotAvailableTimes*)ctr2;
                            if(tna->teacher==tna2->teacher)
                                   break;
                     }
              }
                            
              if(i<this->timeConstraintsList.size())
                     ok=false;
       }
       
       else if(ctr->type==CONSTRAINT_BREAK_TIMES){
              int i;
              for(i=0; i<this->timeConstraintsList.size(); i++){
                     TimeConstraint* ctr2=this->timeConstraintsList[i];
                     if(ctr2->type==CONSTRAINT_BREAK_TIMES)
                            break;
              }
                            
              if(i<this->timeConstraintsList.size())
                     ok=false;
       }
       
       else if(ctr->type==CONSTRAINT_BASIC_COMPULSORY_TIME){
              int i;
              for(i=0; i<this->timeConstraintsList.size(); i++){
                     TimeConstraint* ctr2=this->timeConstraintsList[i];
                     if(ctr2->type==CONSTRAINT_BASIC_COMPULSORY_TIME)
                            break;
              }
                            
              if(i<this->timeConstraintsList.size())
                     ok=false;
       }
       
       if(ok){
              this->timeConstraintsList << ctr; //append
              this->internalStructureComputed=false;
              setRulesModifiedAndOtherThings(this);
              return true;
       }
       else
              return false;
}

Here is the call graph for this function:

bool Rules::addYear ( StudentsYear year)

Adds a new year of study to the academic structure.

Definition at line 2342 of file rules.cpp.

{
       //already existing?
       if(this->searchStudentsSet(year->name)!=NULL)
              return false;
       this->yearsList << year;
       this->internalStructureComputed=false;
       setRulesModifiedAndOtherThings(this);
       return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool Rules::addYearFast ( StudentsYear year)

Definition at line 2353 of file rules.cpp.

{
       this->yearsList << year;
       this->internalStructureComputed=false;
       setRulesModifiedAndOtherThings(this);
       return true;
}

Here is the call graph for this function:

bool Rules::computeInternalStructure ( QWidget *  parent)

Internal structure initializer.

After any modification of the activities or students or teachers or constraints, you need to call this subroutine

Definition at line 131 of file rules.cpp.

{
       //To fix a bug reported by Frans on forum, on 7 May 2010.
       //If user generates, then changes some activities (changes teachers of them), then tries to generate but FET cannot precompute in generate_pre.cpp,
       //then if user views the timetable, the timetable of a teacher contains activities of other teacher.
       //The bug appeared because it is possible to compute internal structure, so internal activities change the teacher, but the timetables remain the same,
       //with the same activities indexes.
       teachers_schedule_ready=false;
       students_schedule_ready=false;
       rooms_schedule_ready=false;

       //The order is important - firstly the teachers, subjects, activity tags and students.
       //After that, the buildings.
       //After that, the rooms.
       //After that, the activities.
       //After that, the time constraints.
       //After that, the space constraints.

       if(this->teachersList.size()>MAX_TEACHERS){
              QMessageBox::warning(parent, tr("FET information"),
               tr("You have too many teachers. You need to increase the variable MAX_TEACHERS (which is currently %1).")
               .arg(MAX_TEACHERS));
              return false;
       }
       if(this->subjectsList.size()>MAX_SUBJECTS){
              QMessageBox::warning(parent, tr("FET information"),
               tr("You have too many subjects. You need to increase the variable MAX_SUBJECTS (which is currently %1).")
               .arg(MAX_SUBJECTS));
              return false;
       }
       
       //kill augmented students sets
       QList<StudentsYear*> ayears;
       QList<StudentsGroup*> agroups;
       QList<StudentsSubgroup*> asubgroups;
       foreach(StudentsYear* year, augmentedYearsList){
              if(!ayears.contains(year))
                     ayears.append(year);
              foreach(StudentsGroup* group, year->groupsList){
                     if(!agroups.contains(group))
                            agroups.append(group);
                     foreach(StudentsSubgroup* subgroup, group->subgroupsList){
                            if(!asubgroups.contains(subgroup))
                                   asubgroups.append(subgroup);
                     }
              }
       }
       foreach(StudentsYear* year, ayears){
              assert(year!=NULL);
              delete year;
       }
       foreach(StudentsGroup* group, agroups){
              assert(group!=NULL);
              delete group;
       }
       foreach(StudentsSubgroup* subgroup, asubgroups){
              assert(subgroup!=NULL);
              delete subgroup;
       }
       augmentedYearsList.clear();
       
       //copy list of students sets into augmented list
       QHash<QString, StudentsSet*> augmentedHash;
       
       foreach(StudentsYear* y, yearsList){
              StudentsYear* ay=new StudentsYear();
              ay->name=y->name;
              ay->numberOfStudents=y->numberOfStudents;
              ay->groupsList.clear();
              augmentedYearsList << ay;
              
              assert(!augmentedHash.contains(ay->name));
              augmentedHash.insert(ay->name, ay);
              
              foreach(StudentsGroup* g, y->groupsList){
                     if(augmentedHash.contains(g->name)){
                            StudentsSet* tmpg=augmentedHash.value(g->name);
                            assert(tmpg->type==STUDENTS_GROUP);
                            ay->groupsList<<((StudentsGroup*)tmpg);
                     }
                     else{
                            StudentsGroup* ag=new StudentsGroup();
                            ag->name=g->name;
                            ag->numberOfStudents=g->numberOfStudents;
                            ag->subgroupsList.clear();
                            ay->groupsList << ag;
                            
                            assert(!augmentedHash.contains(ag->name));
                            augmentedHash.insert(ag->name, ag);
                     
                            foreach(StudentsSubgroup* s, g->subgroupsList){
                                   if(augmentedHash.contains(s->name)){
                                          StudentsSet* tmps=augmentedHash.value(s->name);
                                          assert(tmps->type==STUDENTS_SUBGROUP);
                                          ag->subgroupsList<<((StudentsSubgroup*)tmps);
                                   }
                                   else{
                                          StudentsSubgroup* as=new StudentsSubgroup();
                                          as->name=s->name;
                                          as->numberOfStudents=s->numberOfStudents;
                                          ag->subgroupsList << as;
                                          
                                          assert(!augmentedHash.contains(as->name));
                                          augmentedHash.insert(as->name, as);
                                   }
                            }
                     }
              }
       }

       for(int i=0; i<this->augmentedYearsList.size(); i++){
              StudentsYear* sty=this->augmentedYearsList[i];

              //if this year has no groups, insert something to simulate the whole year
              if(sty->groupsList.count()==0){
                     StudentsGroup* tmpGroup = new StudentsGroup();
                     tmpGroup->name = sty->name+" "+tr("Automatic Group", "Please keep the translation short. It is used when a year contains no groups and an automatic group "
                      "is added in the year, in the timetable (when viewing the students timetable from FET and also in the html timetables for students groups or subgroups)"
                      ". In the empty year there will be added a group with name = yearName+a space character+your translation of 'Automatic Group'.");
                     tmpGroup->numberOfStudents = sty->numberOfStudents;
                     sty->groupsList << tmpGroup;
              }
              
              for(int j=0; j<sty->groupsList.size(); j++){
                     StudentsGroup* stg=sty->groupsList[j];

                     //if this group has no subgroups, insert something to simulate the whole group
                     if(stg->subgroupsList.size()==0){
                            StudentsSubgroup* tmpSubgroup = new StudentsSubgroup();
                            tmpSubgroup->name = stg->name+" "+tr("Automatic Subgroup", "Please keep the translation short. It is used when a group contains no subgroups and an automatic subgroup "
                             "is added in the group, in the timetable (when viewing the students timetable from FET and also in the html timetables for students subgroups)"
                             ". In the empty group there will be added a subgroup with name = groupName+a space character+your translation of 'Automatic Subgroup'.");
                            tmpSubgroup->numberOfStudents=stg->numberOfStudents;
                            stg->subgroupsList << tmpSubgroup;
                     }
              }
       }
       
       QSet<StudentsGroup*> allGroupsSet;
       QSet<StudentsSubgroup*> allSubgroupsSet;
       QList<StudentsGroup*> allGroupsList;
       QList<StudentsSubgroup*> allSubgroupsList;
       
       for(int i=0; i<this->augmentedYearsList.size(); i++){
              StudentsYear* sty=this->augmentedYearsList.at(i);
              sty->indexInAugmentedYearsList=i;

              for(int j=0; j<sty->groupsList.size(); j++){
                     StudentsGroup* stg=sty->groupsList.at(j);
                     if(!allGroupsSet.contains(stg)){
                            allGroupsSet.insert(stg);
                            allGroupsList.append(stg);
                            stg->indexInInternalGroupsList=allGroupsSet.count()-1;
                     }
                     
                     for(int k=0; k<stg->subgroupsList.size(); k++)
                            if(!allSubgroupsSet.contains(stg->subgroupsList.at(k))){
                                   allSubgroupsSet.insert(stg->subgroupsList.at(k));
                                   allSubgroupsList.append(stg->subgroupsList.at(k));
                                   stg->subgroupsList.at(k)->indexInInternalSubgroupsList=allSubgroupsSet.count()-1;
                            }
              }
       }
       int tmpNSubgroups=allSubgroupsList.count();
       if(tmpNSubgroups>MAX_TOTAL_SUBGROUPS){
              QMessageBox::warning(parent, tr("FET information"),
               tr("You have too many total subgroups. You need to increase the variable MAX_TOTAL_SUBGROUPS (which is currently %1).")
               .arg(MAX_TOTAL_SUBGROUPS));
              return false;
       }
       this->internalSubgroupsList.resize(tmpNSubgroups);

       int counter=0;
       for(int i=0; i<this->activitiesList.size(); i++){
              Activity* act=this->activitiesList.at(i);
              if(act->active)
                     counter++;
       }
       if(counter>MAX_ACTIVITIES){
              QMessageBox::warning(parent, tr("FET information"),
               tr("You have too many active activities. You need to increase the variable MAX_ACTIVITIES (which is currently %1).")
               .arg(MAX_ACTIVITIES));
              return false;
       }

       if(this->buildingsList.size()>MAX_BUILDINGS){
              QMessageBox::warning(parent, tr("FET information"),
               tr("You have too many buildings. You need to increase the variable MAX_BUILDINGS (which is currently %1).")
               .arg(MAX_BUILDINGS));
              return false;
       }
       
       if(this->roomsList.size()>MAX_ROOMS){
              QMessageBox::warning(parent, tr("FET information"),
               tr("You have too many rooms. You need to increase the variable MAX_ROOMS (which is currently %1).")
               .arg(MAX_ROOMS));
              return false;
       }
       
       assert(this->initialized);

       //days and hours
       assert(this->nHoursPerDay>0);
       assert(this->nDaysPerWeek>0);
       this->nHoursPerWeek=this->nHoursPerDay*this->nDaysPerWeek;

       //teachers
       int i;
       Teacher* tch;
       this->nInternalTeachers=this->teachersList.size();
       assert(this->nInternalTeachers<=MAX_TEACHERS);
       this->internalTeachersList.resize(this->nInternalTeachers);
       for(i=0; i<this->teachersList.size(); i++){
              tch=teachersList[i];
              this->internalTeachersList[i]=tch;
       }
       assert(i==this->nInternalTeachers);

       //subjects
       Subject* sbj;
       this->nInternalSubjects=this->subjectsList.size();
       assert(this->nInternalSubjects<=MAX_SUBJECTS);
       this->internalSubjectsList.resize(this->nInternalSubjects);
       for(i=0; i<this->subjectsList.size(); i++){
              sbj=this->subjectsList[i];
              this->internalSubjectsList[i]=sbj;
       }
       assert(i==this->nInternalSubjects);

       //activity tags
       ActivityTag* at;
       this->nInternalActivityTags=this->activityTagsList.size();
       this->internalActivityTagsList.resize(this->nInternalActivityTags);
       for(i=0; i<this->activityTagsList.size(); i++){
              at=this->activityTagsList[i];
              this->internalActivityTagsList[i]=at;
       }
       assert(i==this->nInternalActivityTags);

       //students
       this->nInternalSubgroups=0;
       for(int i=0; i<allSubgroupsList.count(); i++){
              assert(allSubgroupsList.at(i)->indexInInternalSubgroupsList==i);
              this->internalSubgroupsList[this->nInternalSubgroups]=allSubgroupsList.at(i);
              this->nInternalSubgroups++;
       }

       this->internalGroupsList.clear();
       for(int i=0; i<allGroupsList.count(); i++){
              assert(allGroupsList.at(i)->indexInInternalGroupsList==i);
              this->internalGroupsList.append(allGroupsList.at(i));
       }
       
/*     for(int i=0; i<this->augmentedYearsList.size(); i++){
              StudentsYear* sty=this->augmentedYearsList[i];
              
              assert(sty->groupsList.count()>0);

              for(int j=0; j<sty->groupsList.size(); j++){
                     StudentsGroup* stg=sty->groupsList[j];
                     
                     assert(stg->subgroupsList.count()>0);

                     for(int k=0; k<stg->subgroupsList.size(); k++){
                            StudentsSubgroup* sts=stg->subgroupsList[k];

                            bool existing=false;
                            for(int i=0; i<this->nInternalSubgroups; i++)
                                   if(this->internalSubgroupsList[i]->name==sts->name){
                                          existing=true;
                                          sts->indexInInternalSubgroupsList=i;
                                          break;
                                   }
                            if(!existing){
                                   assert(this->nInternalSubgroups<MAX_TOTAL_SUBGROUPS);
                                   assert(this->nInternalSubgroups<tmpNSubgroups);
                                   sts->indexInInternalSubgroupsList=this->nInternalSubgroups;
                                   this->internalSubgroupsList[this->nInternalSubgroups++]=sts;
                            }
                     }
              }
       }*/
       assert(this->nInternalSubgroups==tmpNSubgroups);

       //buildings
       internalBuildingsList.resize(buildingsList.size());
       this->nInternalBuildings=0;
       assert(this->buildingsList.size()<=MAX_BUILDINGS);
       for(int i=0; i<this->buildingsList.size(); i++){
              Building* bu=this->buildingsList[i];
              bu->computeInternalStructure(*this);
       }
       
       for(int i=0; i<this->buildingsList.size(); i++){
              Building* bu=this->buildingsList[i];
              this->internalBuildingsList[this->nInternalBuildings++]=bu;
       }
       assert(this->nInternalBuildings==this->buildingsList.size());

       //rooms
       internalRoomsList.resize(roomsList.size());
       this->nInternalRooms=0;
       assert(this->roomsList.size()<=MAX_ROOMS);
       for(int i=0; i<this->roomsList.size(); i++){
              Room* rm=this->roomsList[i];
              rm->computeInternalStructure(*this);
       }
       
       for(int i=0; i<this->roomsList.size(); i++){
              Room* rm=this->roomsList[i];
              this->internalRoomsList[this->nInternalRooms++]=rm;
       }
       assert(this->nInternalRooms==this->roomsList.size());


       //activities
       int range=0;
       foreach(Activity* act, this->activitiesList)
              if(act->active)
                     range++;
       QProgressDialog progress(parent);
       progress.setWindowTitle(tr("Computing internal structure", "Title of a progress dialog"));
       progress.setLabelText(tr("Processing internally the activities ... please wait"));
       progress.setRange(0, range);
       progress.setModal(true);
       int ttt=0;
              
       Activity* act;
       counter=0;
       
       this->inactiveActivities.clear();
       
       for(int i=0; i<this->activitiesList.size(); i++){
              act=this->activitiesList[i];
              if(act->active){
                     progress.setValue(ttt);
                     //pqapplication->processEvents();
                     if(progress.wasCanceled()){
                            QMessageBox::information(parent, tr("FET information"), tr("Canceled"));
                            return false;
                     }
                     ttt++;

                     counter++;
                     act->computeInternalStructure(*this);
              }
              else
                     inactiveActivities.insert(act->id);
       }
       
       progress.setValue(range);

       for(int i=0; i<nInternalSubgroups; i++)
              internalSubgroupsList[i]->activitiesForSubgroup.clear();
       for(int i=0; i<nInternalTeachers; i++)
              internalTeachersList[i]->activitiesForTeacher.clear();

       assert(counter<=MAX_ACTIVITIES);
       this->nInternalActivities=counter;
       this->internalActivitiesList.resize(this->nInternalActivities);
       int activei=0;
       for(int ai=0; ai<this->activitiesList.size(); ai++){
              act=this->activitiesList[ai];
              if(act->active){
                     this->internalActivitiesList[activei]=*act;
                     
                     for(int j=0; j<act->iSubgroupsList.count(); j++){
                            int k=act->iSubgroupsList.at(j);
                            assert(!internalSubgroupsList[k]->activitiesForSubgroup.contains(activei));
                            internalSubgroupsList[k]->activitiesForSubgroup.append(activei);
                     }
                     
                     for(int j=0; j<act->iTeachersList.count(); j++){
                            int k=act->iTeachersList.at(j);
                            assert(!internalTeachersList[k]->activitiesForTeacher.contains(activei));
                            internalTeachersList[k]->activitiesForTeacher.append(activei);
                     }
                     
                     activei++;
              }
       }

       //activities list for each subject - used for subjects timetable - in order for students and teachers
       activitiesForSubject.resize(nInternalSubjects);
       for(int sb=0; sb<nInternalSubjects; sb++)
              activitiesForSubject[sb].clear();

       for(int i=0; i<this->augmentedYearsList.size(); i++){
              StudentsYear* sty=this->augmentedYearsList[i];

              for(int j=0; j<sty->groupsList.size(); j++){
                     StudentsGroup* stg=sty->groupsList[j];

                     for(int k=0; k<stg->subgroupsList.size(); k++){
                            StudentsSubgroup* sts=stg->subgroupsList[k];
                            
                            foreach(int ai, internalSubgroupsList[sts->indexInInternalSubgroupsList]->activitiesForSubgroup)
                                   if(!activitiesForSubject[internalActivitiesList[ai].subjectIndex].contains(ai))
                                          activitiesForSubject[internalActivitiesList[ai].subjectIndex].append(ai);
                     }
              }
       }
       
       for(int i=0; i<nInternalTeachers; i++){
              foreach(int ai, internalTeachersList[i]->activitiesForTeacher)
                     if(!activitiesForSubject[internalActivitiesList[ai].subjectIndex].contains(ai))
                            activitiesForSubject[internalActivitiesList[ai].subjectIndex].append(ai);
       }


       bool ok=true;

       //time constraints
       //progress.reset();
       
       bool skipInactiveTimeConstraints=false;
       
       TimeConstraint* tctr;
       
       QSet<int> toSkipTimeSet;
       
       int _c=0;
       
       for(int tctrindex=0; tctrindex<this->timeConstraintsList.size(); tctrindex++){
              tctr=this->timeConstraintsList[tctrindex];

              if(!tctr->active){
                     toSkipTimeSet.insert(tctrindex);
              }
              else if(tctr->hasInactiveActivities(*this)){
                     //toSkipTime[tctrindex]=true;
                     toSkipTimeSet.insert(tctrindex);
              
                     if(!skipInactiveTimeConstraints){
                            QString s=tr("The following time constraint is ignored, because it refers to inactive activities:");
                            s+="\n";
                            s+=tctr->getDetailedDescription(*this);
                            
                            int t=LongTextMessageBox::mediumConfirmation(parent, tr("FET information"), s,
                             tr("Skip rest"), tr("See next"), QString(),
                             1, 0 );

                            if(t==0)
                                   skipInactiveTimeConstraints=true;
                     }
              }
              else{
                     //toSkipTime[tctrindex]=false;
                     _c++;
              }
       }
       
       internalTimeConstraintsList.resize(_c);
       
       progress.setLabelText(tr("Processing internally the time constraints ... please wait"));
       progress.setRange(0, timeConstraintsList.size());
       ttt=0;
              
       //assert(this->timeConstraintsList.size()<=MAX_TIME_CONSTRAINTS);
       int tctri=0;
       
       for(int tctrindex=0; tctrindex<this->timeConstraintsList.size(); tctrindex++){
              progress.setValue(ttt);
              //pqapplication->processEvents();
              if(progress.wasCanceled()){
                     QMessageBox::information(parent, tr("FET information"), tr("Canceled"));
                     return false;
              }
              ttt++;

              tctr=this->timeConstraintsList[tctrindex];
              
              if(toSkipTimeSet.contains(tctrindex))
                     continue;
              
              if(!tctr->computeInternalStructure(parent, *this)){
                     //assert(0);
                     ok=false;
                     continue;
              }
              this->internalTimeConstraintsList[tctri++]=tctr;
       }

       progress.setValue(timeConstraintsList.size());

       this->nInternalTimeConstraints=tctri;
       cout<<_c<<" time constraints after first pass (after removing inactive ones)"<<endl;
       cout<<"  "<<this->nInternalTimeConstraints<<" time constraints after second pass (after removing wrong ones)"<<endl;
       assert(_c>=this->nInternalTimeConstraints); //because some constraints may have toSkipTime false, but computeInternalStructure also false
       //assert(this->nInternalTimeConstraints<=MAX_TIME_CONSTRAINTS);
       
       //space constraints
       //progress.reset();
       
       bool skipInactiveSpaceConstraints=false;
       
       SpaceConstraint* sctr;
       
       QSet<int> toSkipSpaceSet;
       
       _c=0;

       for(int sctrindex=0; sctrindex<this->spaceConstraintsList.size(); sctrindex++){
              sctr=this->spaceConstraintsList[sctrindex];

              if(!sctr->active){
                     toSkipSpaceSet.insert(sctrindex);
              }
              else if(sctr->hasInactiveActivities(*this)){
                     //toSkipSpace[sctrindex]=true;
                     toSkipSpaceSet.insert(sctrindex);
              
                     if(!skipInactiveSpaceConstraints){
                            QString s=tr("The following space constraint is ignored, because it refers to inactive activities:");
                            s+="\n";
                            s+=sctr->getDetailedDescription(*this);
                            
                            int t=LongTextMessageBox::mediumConfirmation(parent, tr("FET information"), s,
                             tr("Skip rest"), tr("See next"), QString(),
                             1, 0 );

                            if(t==0)
                                   skipInactiveSpaceConstraints=true;
                     }
              }
              else{
                     _c++;
                     //toSkipSpace[sctrindex]=false;
              }
       }
       
       internalSpaceConstraintsList.resize(_c);
       
       progress.setLabelText(tr("Processing internally the space constraints ... please wait"));
       progress.setRange(0, spaceConstraintsList.size());
       ttt=0;
       //assert(this->spaceConstraintsList.size()<=MAX_SPACE_CONSTRAINTS);

       int sctri=0;

       for(int sctrindex=0; sctrindex<this->spaceConstraintsList.size(); sctrindex++){
              progress.setValue(ttt);
              //pqapplication->processEvents();
              if(progress.wasCanceled()){
                     QMessageBox::information(parent, tr("FET information"), tr("Canceled"));
                     return false;
              }
              ttt++;

              sctr=this->spaceConstraintsList[sctrindex];
       
              if(toSkipSpaceSet.contains(sctrindex))
                     continue;
              
              if(!sctr->computeInternalStructure(parent, *this)){
                     //assert(0);
                     ok=false;
                     continue;
              }
              this->internalSpaceConstraintsList[sctri++]=sctr;
       }

       progress.setValue(spaceConstraintsList.size());

       this->nInternalSpaceConstraints=sctri;
       cout<<_c<<" space constraints after first pass (after removing inactive ones)"<<endl;
       cout<<"  "<<this->nInternalSpaceConstraints<<" space constraints after second pass (after removing wrong ones)"<<endl;
       assert(_c>=this->nInternalSpaceConstraints); //because some constraints may have toSkipSpace false, but computeInternalStructure also false
       //assert(this->nInternalSpaceConstraints<=MAX_SPACE_CONSTRAINTS);

       //done.
       this->internalStructureComputed=ok;
       
       return ok;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int Rules::deactivateActivityTag ( const QString &  activityTagName)

Definition at line 7535 of file rules.cpp.

{
       int count=0;
       for(int i=0; i<this->activitiesList.size(); i++){
              Activity* act=this->activitiesList[i];
              if(act->activityTagsNames.contains(activityTagName)){
                     if(act->active)
                            count++;
                     act->active=false;
              }
       }

       this->internalStructureComputed=false;
       setRulesModifiedAndOtherThings(this);
       
       return count;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int Rules::deactivateStudents ( const QString &  studentsName)

Definition at line 7474 of file rules.cpp.

{
       QSet<QString> allSets;
       
       StudentsSet* set=this->searchStudentsSet(studentsName);
       if(set->type==STUDENTS_SUBGROUP)
              allSets.insert(studentsName);
       else if(set->type==STUDENTS_GROUP){
              allSets.insert(studentsName);
              StudentsGroup* g=(StudentsGroup*)set;
              foreach(StudentsSubgroup* s, g->subgroupsList)
                     allSets.insert(s->name);
       }
       else if(set->type==STUDENTS_YEAR){
              allSets.insert(studentsName);
              StudentsYear* y=(StudentsYear*)set;
              foreach(StudentsGroup* g, y->groupsList){
                     allSets.insert(g->name);
                     foreach(StudentsSubgroup* s, g->subgroupsList)
                            allSets.insert(s->name);
              }
       }

       int count=0;
       for(int i=0; i<this->activitiesList.size(); i++){
              Activity* act=this->activitiesList[i];
              if(act->active){
                     foreach(QString set, act->studentsNames){
                            if(allSets.contains(set)){
                                   count++;
                                   act->active=false;
                                   break;
                            }
                     }
              }
       }

       this->internalStructureComputed=false;
       setRulesModifiedAndOtherThings(this);
       
       return count;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int Rules::deactivateSubject ( const QString &  subjectName)

Definition at line 7517 of file rules.cpp.

{
       int count=0;
       for(int i=0; i<this->activitiesList.size(); i++){
              Activity* act=this->activitiesList[i];
              if(act->subjectName==subjectName){
                     if(act->active)
                            count++;
                     act->active=false;
              }
       }

       this->internalStructureComputed=false;
       setRulesModifiedAndOtherThings(this);
       
       return count;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int Rules::deactivateTeacher ( const QString &  teacherName)

Definition at line 7456 of file rules.cpp.

{
       int count=0;
       for(int i=0; i<this->activitiesList.size(); i++){
              Activity* act=this->activitiesList[i];
              if(act->searchTeacher(teacherName)){
                     if(act->active)
                            count++;
                     act->active=false;
              }
       }

       this->internalStructureComputed=false;
       setRulesModifiedAndOtherThings(this);
       
       return count;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void Rules::init ( )

Initializes the rules (empty)

Definition at line 100 of file rules.cpp.

{
       //defaults
       this->nHoursPerDay=12;
       this->hoursOfTheDay[0]="08:00";
       this->hoursOfTheDay[1]="09:00";
       this->hoursOfTheDay[2]="10:00";
       this->hoursOfTheDay[3]="11:00";
       this->hoursOfTheDay[4]="12:00";
       this->hoursOfTheDay[5]="13:00";
       this->hoursOfTheDay[6]="14:00";
       this->hoursOfTheDay[7]="15:00";
       this->hoursOfTheDay[8]="16:00";
       this->hoursOfTheDay[9]="17:00";
       this->hoursOfTheDay[10]="18:00";
       this->hoursOfTheDay[11]="19:00";
       this->hoursOfTheDay[12]="20:00";

       this->nDaysPerWeek=5;
       this->daysOfTheWeek[0] = tr("Monday");
       this->daysOfTheWeek[1] = tr("Tuesday");
       this->daysOfTheWeek[2] = tr("Wednesday");
       this->daysOfTheWeek[3] = tr("Thursday");
       this->daysOfTheWeek[4] = tr("Friday");
       
       this->institutionName=tr("Default institution");
       this->comments=tr("Default comments");

       this->initialized=true;
}

Here is the caller graph for this function:

void Rules::kill ( )

Terminator - basically clears the memory for the constraints.

Definition at line 711 of file rules.cpp.

{
       //Teachers
       while(!teachersList.isEmpty())
              delete teachersList.takeFirst();

       //Subjects
       while(!subjectsList.isEmpty())
              delete subjectsList.takeFirst();

       //Activity tags
       while(!activityTagsList.isEmpty())
              delete activityTagsList.takeFirst();

       //Years
       /*while(!yearsList.isEmpty())
              delete yearsList.takeFirst();*/
              
       //students sets
       QList<StudentsYear*> iyears;
       QList<StudentsGroup*> igroups;
       QList<StudentsSubgroup*> isubgroups;
       foreach(StudentsYear* year, yearsList){
              if(!iyears.contains(year))
                     iyears.append(year);
              foreach(StudentsGroup* group, year->groupsList){
                     if(!igroups.contains(group))
                            igroups.append(group);
                     foreach(StudentsSubgroup* subgroup, group->subgroupsList){
                            if(!isubgroups.contains(subgroup))
                                   isubgroups.append(subgroup);
                     }
              }
       }
       foreach(StudentsYear* year, iyears){
              assert(year!=NULL);
              delete year;
       }
       foreach(StudentsGroup* group, igroups){
              assert(group!=NULL);
              delete group;
       }
       foreach(StudentsSubgroup* subgroup, isubgroups){
              assert(subgroup!=NULL);
              delete subgroup;
       }      
       yearsList.clear();

       //kill augmented students sets
       QList<StudentsYear*> ayears;
       QList<StudentsGroup*> agroups;
       QList<StudentsSubgroup*> asubgroups;
       foreach(StudentsYear* year, augmentedYearsList){
              if(!ayears.contains(year))
                     ayears.append(year);
              foreach(StudentsGroup* group, year->groupsList){
                     if(!agroups.contains(group))
                            agroups.append(group);
                     foreach(StudentsSubgroup* subgroup, group->subgroupsList){
                            if(!asubgroups.contains(subgroup))
                                   asubgroups.append(subgroup);
                     }
              }
       }
       foreach(StudentsYear* year, ayears){
              assert(year!=NULL);
              delete year;
       }
       foreach(StudentsGroup* group, agroups){
              assert(group!=NULL);
              delete group;
       }
       foreach(StudentsSubgroup* subgroup, asubgroups){
              assert(subgroup!=NULL);
              delete subgroup;
       }      
       augmentedYearsList.clear();
       
       //Activities
       while(!activitiesList.isEmpty())
              delete activitiesList.takeFirst();

       //Time constraints
       while(!timeConstraintsList.isEmpty())
              delete timeConstraintsList.takeFirst();

       //Space constraints
       while(!spaceConstraintsList.isEmpty())
              delete spaceConstraintsList.takeFirst();

       //Buildings
       while(!buildingsList.isEmpty())
              delete buildingsList.takeFirst();

       //Rooms
       while(!roomsList.isEmpty())
              delete roomsList.takeFirst();

       //done
       this->internalStructureComputed=false;
       this->initialized=false;
}

Here is the caller graph for this function:

void Rules::modifyActivity ( int  _id,
int  _activityGroupId,
const QStringList &  _teachersNames,
const QString &  _subjectName,
const QStringList &  _activityTagsNames,
const QStringList &  _studentsNames,
int  _nSplits,
int  _totalDuration,
int  _durations[],
bool  _active[],
bool  _computeNTotalStudents,
int  nTotalStudents 
)

A function to modify the information of a certain activity.

If this is a sub-activity of a split activity, all the sub-activities will be modified.

Definition at line 4518 of file rules.cpp.

{
       int i=0;
       for(int j=0; j<this->activitiesList.size(); j++){
              Activity* act=this->activitiesList[j];
              if((_activityGroupId==0 && act->id==_id) || (_activityGroupId!=0 && act->activityGroupId==_activityGroupId)){
                     act->teachersNames=_teachersNames;
                     act->subjectName=_subjectName;
                     act->activityTagsNames=_activityTagsNames;
                     act->studentsNames=_studentsNames;
                     act->duration=_durations[i];
                     //act->parity=_parities[i];
                     act->active=_active[i];
                     act->totalDuration=_totalDuration;
                     act->computeNTotalStudents=_computeNTotalStudents;
                     act->nTotalStudents=_nTotalStudents;
                     i++;
              }
       }
              
       assert(i==_nSplits);
       
       this->internalStructureComputed=false;
       setRulesModifiedAndOtherThings(this);
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool Rules::modifyActivityTag ( const QString &  initialActivityTagName,
const QString &  finalActivityTagName 
)

Modifies (renames) this activity tag and takes care of all related activities.

Returns true on success, false on failure (if not found)

Definition at line 2040 of file rules.cpp.

{
       assert(this->searchActivityTag(finalActivityTagName)==-1);
       assert(this->searchActivityTag(initialActivityTagName)>=0);

       //check the activities first
       for(int i=0; i<this->activitiesList.size(); i++){
              Activity* act=this->activitiesList[i];

              //if( act->activityTagName == initialActivityTagName)
              //     act->activityTagName=finalActivityTagName;
              for(int kk=0; kk<act->activityTagsNames.count(); kk++)
                     if(act->activityTagsNames.at(kk)==initialActivityTagName)
                            act->activityTagsNames[kk]=finalActivityTagName;
       }
       
       //modify the constraints related to this activity tag
       for(int i=0; i<this->timeConstraintsList.size(); i++){
              TimeConstraint* ctr=this->timeConstraintsList[i];
       
              if(ctr->type==CONSTRAINT_TEACHER_ACTIVITY_TAG_MAX_HOURS_CONTINUOUSLY){
                     ConstraintTeacherActivityTagMaxHoursContinuously* crt_constraint=(ConstraintTeacherActivityTagMaxHoursContinuously*)ctr;
                     if(initialActivityTagName == crt_constraint->activityTagName)
                            crt_constraint->activityTagName=finalActivityTagName;
              }
       }
       for(int i=0; i<this->timeConstraintsList.size(); i++){
              TimeConstraint* ctr=this->timeConstraintsList[i];
       
              if(ctr->type==CONSTRAINT_TEACHER_ACTIVITY_TAG_MAX_HOURS_DAILY){
                     ConstraintTeacherActivityTagMaxHoursDaily* crt_constraint=(ConstraintTeacherActivityTagMaxHoursDaily*)ctr;
                     if(initialActivityTagName == crt_constraint->activityTagName)
                            crt_constraint->activityTagName=finalActivityTagName;
              }
       }
       for(int i=0; i<this->timeConstraintsList.size(); i++){
              TimeConstraint* ctr=this->timeConstraintsList[i];
       
              if(ctr->type==CONSTRAINT_TEACHERS_ACTIVITY_TAG_MAX_HOURS_CONTINUOUSLY){
                     ConstraintTeachersActivityTagMaxHoursContinuously* crt_constraint=(ConstraintTeachersActivityTagMaxHoursContinuously*)ctr;
                     if(initialActivityTagName == crt_constraint->activityTagName)
                            crt_constraint->activityTagName=finalActivityTagName;
              }
       }
       for(int i=0; i<this->timeConstraintsList.size(); i++){
              TimeConstraint* ctr=this->timeConstraintsList[i];
       
              if(ctr->type==CONSTRAINT_TEACHERS_ACTIVITY_TAG_MAX_HOURS_DAILY){
                     ConstraintTeachersActivityTagMaxHoursDaily* crt_constraint=(ConstraintTeachersActivityTagMaxHoursDaily*)ctr;
                     if(initialActivityTagName == crt_constraint->activityTagName)
                            crt_constraint->activityTagName=finalActivityTagName;
              }
       }
       for(int i=0; i<this->timeConstraintsList.size(); i++){
              TimeConstraint* ctr=this->timeConstraintsList[i];
       
              if(ctr->type==CONSTRAINT_STUDENTS_ACTIVITY_TAG_MAX_HOURS_CONTINUOUSLY){
                     ConstraintStudentsActivityTagMaxHoursContinuously* crt_constraint=(ConstraintStudentsActivityTagMaxHoursContinuously*)ctr;
                     if(initialActivityTagName == crt_constraint->activityTagName)
                            crt_constraint->activityTagName=finalActivityTagName;
              }
       }
       for(int i=0; i<this->timeConstraintsList.size(); i++){
              TimeConstraint* ctr=this->timeConstraintsList[i];
       
              if(ctr->type==CONSTRAINT_STUDENTS_ACTIVITY_TAG_MAX_HOURS_DAILY){
                     ConstraintStudentsActivityTagMaxHoursDaily* crt_constraint=(ConstraintStudentsActivityTagMaxHoursDaily*)ctr;
                     if(initialActivityTagName == crt_constraint->activityTagName)
                            crt_constraint->activityTagName=finalActivityTagName;
              }
       }
       for(int i=0; i<this->timeConstraintsList.size(); i++){
              TimeConstraint* ctr=this->timeConstraintsList[i];
       
              if(ctr->type==CONSTRAINT_STUDENTS_SET_ACTIVITY_TAG_MAX_HOURS_CONTINUOUSLY){
                     ConstraintStudentsSetActivityTagMaxHoursContinuously* crt_constraint=(ConstraintStudentsSetActivityTagMaxHoursContinuously*)ctr;
                     if(initialActivityTagName == crt_constraint->activityTagName)
                            crt_constraint->activityTagName=finalActivityTagName;
              }
       }
       for(int i=0; i<this->timeConstraintsList.size(); i++){
              TimeConstraint* ctr=this->timeConstraintsList[i];
       
              if(ctr->type==CONSTRAINT_STUDENTS_SET_ACTIVITY_TAG_MAX_HOURS_DAILY){
                     ConstraintStudentsSetActivityTagMaxHoursDaily* crt_constraint=(ConstraintStudentsSetActivityTagMaxHoursDaily*)ctr;
                     if(initialActivityTagName == crt_constraint->activityTagName)
                            crt_constraint->activityTagName=finalActivityTagName;
              }
       }

       //modify the constraints related to this activity tag
       for(int i=0; i<this->timeConstraintsList.size(); i++){
              TimeConstraint* ctr=this->timeConstraintsList[i];
       
              if(ctr->type==CONSTRAINT_ACTIVITIES_PREFERRED_TIME_SLOTS){
                     ConstraintActivitiesPreferredTimeSlots* crt_constraint=(ConstraintActivitiesPreferredTimeSlots*)ctr;
                     if(initialActivityTagName == crt_constraint->p_activityTagName)
                            crt_constraint->p_activityTagName=finalActivityTagName;
              }
       }

       //modify the constraints related to this activity tag
       for(int i=0; i<this->timeConstraintsList.size(); i++){
              TimeConstraint* ctr=this->timeConstraintsList[i];
       
              if(ctr->type==CONSTRAINT_ACTIVITIES_PREFERRED_STARTING_TIMES){
                     ConstraintActivitiesPreferredStartingTimes* crt_constraint=(ConstraintActivitiesPreferredStartingTimes*)ctr;
                     if(initialActivityTagName == crt_constraint->activityTagName)
                            crt_constraint->activityTagName=finalActivityTagName;
              }
       }

       //modify the constraints related to this activity tag
       for(int i=0; i<this->timeConstraintsList.size(); i++){
              TimeConstraint* ctr=this->timeConstraintsList[i];
       
              if(ctr->type==CONSTRAINT_ACTIVITIES_END_STUDENTS_DAY){
                     ConstraintActivitiesEndStudentsDay* crt_constraint=(ConstraintActivitiesEndStudentsDay*)ctr;
                     if(initialActivityTagName == crt_constraint->activityTagName)
                            crt_constraint->activityTagName=finalActivityTagName;
              }
       }

       //modify the constraints related to this activity tag
       for(int i=0; i<this->timeConstraintsList.size(); i++){
              TimeConstraint* ctr=this->timeConstraintsList[i];
       
              if(ctr->type==CONSTRAINT_SUBACTIVITIES_PREFERRED_TIME_SLOTS){
                     ConstraintSubactivitiesPreferredTimeSlots* crt_constraint=(ConstraintSubactivitiesPreferredTimeSlots*)ctr;
                     if(initialActivityTagName == crt_constraint->p_activityTagName)
                            crt_constraint->p_activityTagName=finalActivityTagName;
              }
       }

       //modify the constraints related to this activity tag
       for(int i=0; i<this->timeConstraintsList.size(); i++){
              TimeConstraint* ctr=this->timeConstraintsList[i];
       
              if(ctr->type==CONSTRAINT_SUBACTIVITIES_PREFERRED_STARTING_TIMES){
                     ConstraintSubactivitiesPreferredStartingTimes* crt_constraint=(ConstraintSubactivitiesPreferredStartingTimes*)ctr;
                     if(initialActivityTagName == crt_constraint->activityTagName)
                            crt_constraint->activityTagName=finalActivityTagName;
              }
       }

       //modify the space constraints related to this subject tag
       for(int i=0; i<this->spaceConstraintsList.size(); i++){
              SpaceConstraint* ctr=this->spaceConstraintsList[i];

              if(ctr->type==CONSTRAINT_SUBJECT_ACTIVITY_TAG_PREFERRED_ROOM){
                     ConstraintSubjectActivityTagPreferredRoom* c=(ConstraintSubjectActivityTagPreferredRoom*)ctr;
                     if(c->activityTagName == initialActivityTagName)
                            c->activityTagName=finalActivityTagName;
              }
              else if(ctr->type==CONSTRAINT_SUBJECT_ACTIVITY_TAG_PREFERRED_ROOMS){
                     ConstraintSubjectActivityTagPreferredRooms* c=(ConstraintSubjectActivityTagPreferredRooms*)ctr;
                     if(c->activityTagName == initialActivityTagName)
                            c->activityTagName=finalActivityTagName;
              }
              else if(ctr->type==CONSTRAINT_ACTIVITY_TAG_PREFERRED_ROOM){
                     ConstraintActivityTagPreferredRoom* c=(ConstraintActivityTagPreferredRoom*)ctr;
                     if(c->activityTagName == initialActivityTagName)
                            c->activityTagName=finalActivityTagName;
              }
              else if(ctr->type==CONSTRAINT_ACTIVITY_TAG_PREFERRED_ROOMS){
                     ConstraintActivityTagPreferredRooms* c=(ConstraintActivityTagPreferredRooms*)ctr;
                     if(c->activityTagName == initialActivityTagName)
                            c->activityTagName=finalActivityTagName;
              }
       }

       //rename the activity tag in the list
       int t=0;
       
       for(int i=0; i<this->activityTagsList.size(); i++){
              ActivityTag* sbt=this->activityTagsList[i];

              if(sbt->name==initialActivityTagName){
                     t++;
                     sbt->name=finalActivityTagName;
              }
       }
       
       assert(t<=1);

       this->internalStructureComputed=false;
       setRulesModifiedAndOtherThings(this);

       return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool Rules::modifyBuilding ( const QString &  initialBuildingName,
const QString &  finalBuildingName 
)

Modifies this building and takes care of all related constraints.

Returns true on success, false on failure (if not found)

Definition at line 5077 of file rules.cpp.

{
       foreach(Room* rm, roomsList)
              if(rm->building==initialBuildingName)
                     rm->building=finalBuildingName;

       int i=this->searchBuilding(initialBuildingName);
       if(i<0)
              return false;

       Building* searchedBuilding=this->buildingsList[i];
       assert(searchedBuilding->name==initialBuildingName);
       searchedBuilding->name=finalBuildingName;

       this->internalStructureComputed=false;
       setRulesModifiedAndOtherThings(this);
       return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool Rules::modifyGroup ( const QString &  yearName,
const QString &  initialGroupName,
const QString &  finalGroupName,
int  finalNumberOfStudents 
)

Modifies this students group (name, number of students) and takes care of all related activities and constraints.

Returns true on success, false on failure (if not found)

Definition at line 3073 of file rules.cpp.

{
       StudentsSet* _initialSet=searchStudentsSet(initialGroupName);
       assert(_initialSet!=NULL);
       int _initialNumberOfStudents=_initialSet->numberOfStudents;

       //cout<<"Begin: initialGroupName=='"<<qPrintableinitialGroupName<<"'"<<endl;
       
       QString _initialGroupName=initialGroupName;

       assert(searchGroup(yearName, _initialGroupName)>=0);
       StudentsSet* _ss=searchStudentsSet(finalGroupName);
       assert(_ss==NULL || _initialGroupName==finalGroupName);

       StudentsYear* sty=NULL;
       for(int i=0; i<this->yearsList.size(); i++){
              sty=this->yearsList[i];
              if(sty->name==yearName)
                     break;
       }
       assert(sty);
       
       StudentsGroup* stg=NULL;
       for(int i=0; i<sty->groupsList.size(); i++){
              stg=sty->groupsList[i];
              if(stg->name==_initialGroupName){
                     stg->name=finalGroupName;
                     stg->numberOfStudents=finalNumberOfStudents;

                     break;
              }
       }
       assert(stg);
       
       if(_ss!=NULL){ //In case it only changes the number of students, make the same number of students in all groups with this name
              assert(_initialGroupName==finalGroupName);
              foreach(StudentsYear* year, yearsList)
                     foreach(StudentsGroup* group, year->groupsList)
                            if(group->name==finalGroupName)
                                   group->numberOfStudents=finalNumberOfStudents;
       }

       for(int i=0; i<this->activitiesList.size(); i++)
              this->activitiesList[i]->renameStudents(*this, _initialGroupName, finalGroupName, _initialNumberOfStudents, finalNumberOfStudents);
       
       for(int i=0; i<this->timeConstraintsList.size(); i++){
              TimeConstraint* ctr=this->timeConstraintsList[i];

              if(ctr->type==CONSTRAINT_STUDENTS_SET_NOT_AVAILABLE_TIMES){
                     ConstraintStudentsSetNotAvailableTimes* crt_constraint=(ConstraintStudentsSetNotAvailableTimes*)ctr;
                     if(_initialGroupName == crt_constraint->students)
                            crt_constraint->students=finalGroupName;
              }
              else if(ctr->type==CONSTRAINT_STUDENTS_SET_MAX_HOURS_DAILY){
                     ConstraintStudentsSetMaxHoursDaily* crt_constraint=(ConstraintStudentsSetMaxHoursDaily*)ctr;
                     if(_initialGroupName == crt_constraint->students)
                            crt_constraint->students=finalGroupName;
              }
              else if(ctr->type==CONSTRAINT_STUDENTS_SET_INTERVAL_MAX_DAYS_PER_WEEK){
                     ConstraintStudentsSetIntervalMaxDaysPerWeek* crt_constraint=(ConstraintStudentsSetIntervalMaxDaysPerWeek*)ctr;
                     if(_initialGroupName == crt_constraint->students)
                            crt_constraint->students=finalGroupName;
              }
              else if(ctr->type==CONSTRAINT_STUDENTS_SET_MAX_HOURS_CONTINUOUSLY){
                     ConstraintStudentsSetMaxHoursContinuously* crt_constraint=(ConstraintStudentsSetMaxHoursContinuously*)ctr;
                     if(_initialGroupName == crt_constraint->students)
                            crt_constraint->students=finalGroupName;
              }
              else if(ctr->type==CONSTRAINT_STUDENTS_SET_ACTIVITY_TAG_MAX_HOURS_CONTINUOUSLY){
                     ConstraintStudentsSetActivityTagMaxHoursContinuously* crt_constraint=(ConstraintStudentsSetActivityTagMaxHoursContinuously*)ctr;
                     if(_initialGroupName == crt_constraint->students)
                            crt_constraint->students=finalGroupName;
              }
              else if(ctr->type==CONSTRAINT_STUDENTS_SET_ACTIVITY_TAG_MAX_HOURS_DAILY){
                     ConstraintStudentsSetActivityTagMaxHoursDaily* crt_constraint=(ConstraintStudentsSetActivityTagMaxHoursDaily*)ctr;
                     if(_initialGroupName == crt_constraint->students)
                            crt_constraint->students=finalGroupName;
              }
              else if(ctr->type==CONSTRAINT_STUDENTS_SET_MIN_HOURS_DAILY){
                     ConstraintStudentsSetMinHoursDaily* crt_constraint=(ConstraintStudentsSetMinHoursDaily*)ctr;
                     if(_initialGroupName == crt_constraint->students)
                            crt_constraint->students=finalGroupName;
              }
              else if(ctr->type==CONSTRAINT_STUDENTS_SET_EARLY_MAX_BEGINNINGS_AT_SECOND_HOUR){
                     ConstraintStudentsSetEarlyMaxBeginningsAtSecondHour* crt_constraint=(ConstraintStudentsSetEarlyMaxBeginningsAtSecondHour*)ctr;
                     if(_initialGroupName == crt_constraint->students)
                            crt_constraint->students=finalGroupName;
              }
              else if(ctr->type==CONSTRAINT_STUDENTS_SET_MAX_GAPS_PER_WEEK){
                     ConstraintStudentsSetMaxGapsPerWeek* crt_constraint=(ConstraintStudentsSetMaxGapsPerWeek*)ctr;
                     if(_initialGroupName == crt_constraint->students)
                            crt_constraint->students=finalGroupName;
              }
              else if(ctr->type==CONSTRAINT_STUDENTS_SET_MAX_GAPS_PER_DAY){
                     ConstraintStudentsSetMaxGapsPerDay* crt_constraint=(ConstraintStudentsSetMaxGapsPerDay*)ctr;
                     if(_initialGroupName == crt_constraint->students)
                            crt_constraint->students=finalGroupName;
              }
              else if(ctr->type==CONSTRAINT_ACTIVITIES_PREFERRED_TIME_SLOTS){
                     ConstraintActivitiesPreferredTimeSlots* crt_constraint=(ConstraintActivitiesPreferredTimeSlots*)ctr;
                     if(_initialGroupName == crt_constraint->p_studentsName)
                            crt_constraint->p_studentsName=finalGroupName;
              }
              else if(ctr->type==CONSTRAINT_ACTIVITIES_PREFERRED_STARTING_TIMES){
                     ConstraintActivitiesPreferredStartingTimes* crt_constraint=(ConstraintActivitiesPreferredStartingTimes*)ctr;
                     if(_initialGroupName == crt_constraint->studentsName)
                            crt_constraint->studentsName=finalGroupName;
              }
              else if(ctr->type==CONSTRAINT_ACTIVITIES_END_STUDENTS_DAY){
                     ConstraintActivitiesEndStudentsDay* crt_constraint=(ConstraintActivitiesEndStudentsDay*)ctr;
                     if(_initialGroupName == crt_constraint->studentsName)
                            crt_constraint->studentsName=finalGroupName;
              }
              else if(ctr->type==CONSTRAINT_SUBACTIVITIES_PREFERRED_TIME_SLOTS){
                     ConstraintSubactivitiesPreferredTimeSlots* crt_constraint=(ConstraintSubactivitiesPreferredTimeSlots*)ctr;
                     if(_initialGroupName == crt_constraint->p_studentsName)
                            crt_constraint->p_studentsName=finalGroupName;
              }
              else if(ctr->type==CONSTRAINT_SUBACTIVITIES_PREFERRED_STARTING_TIMES){
                     ConstraintSubactivitiesPreferredStartingTimes* crt_constraint=(ConstraintSubactivitiesPreferredStartingTimes*)ctr;
                     if(_initialGroupName == crt_constraint->studentsName)
                            crt_constraint->studentsName=finalGroupName;
              }
       }

       for(int i=0; i<this->spaceConstraintsList.size(); i++){
              SpaceConstraint* ctr=this->spaceConstraintsList[i];

              if(ctr->type==CONSTRAINT_STUDENTS_SET_HOME_ROOM){
                     ConstraintStudentsSetHomeRoom* crt_constraint=(ConstraintStudentsSetHomeRoom*)ctr;
                     if(_initialGroupName == crt_constraint->studentsName)
                            crt_constraint->studentsName=finalGroupName;
              }
              else if(ctr->type==CONSTRAINT_STUDENTS_SET_HOME_ROOMS){
                     ConstraintStudentsSetHomeRooms* crt_constraint=(ConstraintStudentsSetHomeRooms*)ctr;
                     if(_initialGroupName == crt_constraint->studentsName)
                            crt_constraint->studentsName=finalGroupName;
              }
              else if(ctr->type==CONSTRAINT_STUDENTS_SET_MAX_BUILDING_CHANGES_PER_DAY){
                     ConstraintStudentsSetMaxBuildingChangesPerDay* crt_constraint=(ConstraintStudentsSetMaxBuildingChangesPerDay*)ctr;
                     if(_initialGroupName == crt_constraint->studentsName)
                            crt_constraint->studentsName=finalGroupName;
              }
              else if(ctr->type==CONSTRAINT_STUDENTS_SET_MAX_BUILDING_CHANGES_PER_WEEK){
                     ConstraintStudentsSetMaxBuildingChangesPerWeek* crt_constraint=(ConstraintStudentsSetMaxBuildingChangesPerWeek*)ctr;
                     if(_initialGroupName == crt_constraint->studentsName)
                            crt_constraint->studentsName=finalGroupName;
              }
              else if(ctr->type==CONSTRAINT_STUDENTS_SET_MIN_GAPS_BETWEEN_BUILDING_CHANGES){
                     ConstraintStudentsSetMinGapsBetweenBuildingChanges* crt_constraint=(ConstraintStudentsSetMinGapsBetweenBuildingChanges*)ctr;
                     if(_initialGroupName == crt_constraint->studentsName)
                            crt_constraint->studentsName=finalGroupName;
              }
       }

       this->internalStructureComputed=false;
       setRulesModifiedAndOtherThings(this);

       return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool Rules::modifyRoom ( const QString &  initialRoomName,
const QString &  finalRoomName,
const QString &  building,
int  capacity 
)

Modifies this room and takes care of all related constraints.

Returns true on success, false on failure (if not found)

Definition at line 4866 of file rules.cpp.

{
       int i=this->searchRoom(initialRoomName);
       if(i<0)
              return false;

       Room* searchedRoom=this->roomsList[i];
       assert(searchedRoom->name==initialRoomName);

       for(int j=0; j<this->spaceConstraintsList.size(); ){
              SpaceConstraint* ctr=this->spaceConstraintsList[j];
              if(ctr->type==CONSTRAINT_ROOM_NOT_AVAILABLE_TIMES){
                     ConstraintRoomNotAvailableTimes* crna=(ConstraintRoomNotAvailableTimes*)ctr;
                     if(crna->room==initialRoomName)
                            crna->room=finalRoomName;
                     j++;
              }
              else if(ctr->type==CONSTRAINT_ACTIVITY_PREFERRED_ROOM){
                     ConstraintActivityPreferredRoom* c=(ConstraintActivityPreferredRoom*)ctr;
                     if(c->roomName==initialRoomName)
                            c->roomName=finalRoomName;
                     j++;
              }
              else if(ctr->type==CONSTRAINT_ACTIVITY_PREFERRED_ROOMS){
                     ConstraintActivityPreferredRooms* c=(ConstraintActivityPreferredRooms*)ctr;
                     int t=0;
                     for(QStringList::Iterator it=c->roomsNames.begin(); it!=c->roomsNames.end(); it++){
                            if((*it)==initialRoomName){
                                   *it=finalRoomName;
                                   t++;
                            }
                     }
                     assert(t<=1);
                     j++;
              }
              else if(ctr->type==CONSTRAINT_STUDENTS_SET_HOME_ROOM){
                     ConstraintStudentsSetHomeRoom* c=(ConstraintStudentsSetHomeRoom*)ctr;
                     if(c->roomName==initialRoomName)
                            c->roomName=finalRoomName;
                     j++;
              }
              else if(ctr->type==CONSTRAINT_STUDENTS_SET_HOME_ROOMS){
                     ConstraintStudentsSetHomeRooms* c=(ConstraintStudentsSetHomeRooms*)ctr;
                     int t=0;
                     for(QStringList::Iterator it=c->roomsNames.begin(); it!=c->roomsNames.end(); it++){
                            if((*it)==initialRoomName){
                                   *it=finalRoomName;
                                   t++;
                            }
                     }
                     assert(t<=1);
                     j++;
              }
              else if(ctr->type==CONSTRAINT_TEACHER_HOME_ROOM){
                     ConstraintTeacherHomeRoom* c=(ConstraintTeacherHomeRoom*)ctr;
                     if(c->roomName==initialRoomName)
                            c->roomName=finalRoomName;
                     j++;
              }
              else if(ctr->type==CONSTRAINT_TEACHER_HOME_ROOMS){
                     ConstraintTeacherHomeRooms* c=(ConstraintTeacherHomeRooms*)ctr;
                     int t=0;
                     for(QStringList::Iterator it=c->roomsNames.begin(); it!=c->roomsNames.end(); it++){
                            if((*it)==initialRoomName){
                                   *it=finalRoomName;
                                   t++;
                            }
                     }
                     assert(t<=1);
                     j++;
              }
              else if(ctr->type==CONSTRAINT_SUBJECT_PREFERRED_ROOM){
                     ConstraintSubjectPreferredRoom* c=(ConstraintSubjectPreferredRoom*)ctr;
                     if(c->roomName==initialRoomName)
                            c->roomName=finalRoomName;
                     j++;
              }
              else if(ctr->type==CONSTRAINT_SUBJECT_PREFERRED_ROOMS){
                     ConstraintSubjectPreferredRooms* c=(ConstraintSubjectPreferredRooms*)ctr;
                     int t=0;
                     for(QStringList::Iterator it=c->roomsNames.begin(); it!=c->roomsNames.end(); it++){
                            if((*it)==initialRoomName){
                                   *it=finalRoomName;
                                   t++;
                            }
                     }
                     assert(t<=1);
                     j++;
              }
              else if(ctr->type==CONSTRAINT_SUBJECT_ACTIVITY_TAG_PREFERRED_ROOM){
                     ConstraintSubjectActivityTagPreferredRoom* c=(ConstraintSubjectActivityTagPreferredRoom*)ctr;
                     if(c->roomName==initialRoomName)
                            c->roomName=finalRoomName;
                     j++;
              }
              else if(ctr->type==CONSTRAINT_SUBJECT_ACTIVITY_TAG_PREFERRED_ROOMS){
                     ConstraintSubjectActivityTagPreferredRooms* c=(ConstraintSubjectActivityTagPreferredRooms*)ctr;
                     int t=0;
                     for(QStringList::Iterator it=c->roomsNames.begin(); it!=c->roomsNames.end(); it++){
                            if((*it)==initialRoomName){
                                   *it=finalRoomName;
                                   t++;
                            }
                     }
                     assert(t<=1);
                     j++;
              }

              else if(ctr->type==CONSTRAINT_ACTIVITY_TAG_PREFERRED_ROOM){
                     ConstraintActivityTagPreferredRoom* c=(ConstraintActivityTagPreferredRoom*)ctr;
                     if(c->roomName==initialRoomName)
                            c->roomName=finalRoomName;
                     j++;
              }
              else if(ctr->type==CONSTRAINT_ACTIVITY_TAG_PREFERRED_ROOMS){
                     ConstraintActivityTagPreferredRooms* c=(ConstraintActivityTagPreferredRooms*)ctr;
                     int t=0;
                     for(QStringList::Iterator it=c->roomsNames.begin(); it!=c->roomsNames.end(); it++){
                            if((*it)==initialRoomName){
                                   *it=finalRoomName;
                                   t++;
                            }
                     }
                     assert(t<=1);
                     j++;
              }

              else
                     j++;
       }

       searchedRoom->name=finalRoomName;
       searchedRoom->building=building;
       searchedRoom->capacity=capacity;

       this->internalStructureComputed=false;
       setRulesModifiedAndOtherThings(this);
       return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void Rules::modifySubactivity ( int  _id,
int  _activityGroupId,
const QStringList &  _teachersNames,
const QString &  _subjectName,
const QStringList &  _activityTagsNames,
const QStringList &  _studentsNames,
int  _duration,
bool  _active,
bool  _computeNTotalStudents,
int  nTotalStudents 
)

Definition at line 4558 of file rules.cpp.

{
       QList<Activity*> actsList;
       Activity* crtAct=NULL;
       
       foreach(Activity* act, this->activitiesList){
              if(act->id==_id && act->activityGroupId==_activityGroupId){
                     crtAct=act;
                     //actsList.append(act);
              }
              else if(act->activityGroupId!=0 && _activityGroupId!=0 && act->activityGroupId==_activityGroupId){
                     actsList.append(act);
              }
       }
       
       assert(crtAct!=NULL);
       
       int td=0;
       foreach(Activity* act, actsList)
              td+=act->duration;
       td+=_duration; //crtAct->duration;
       foreach(Activity* act, actsList)
              act->totalDuration=td;

       crtAct->teachersNames=_teachersNames;
       crtAct->subjectName=_subjectName;
       crtAct->activityTagsNames=_activityTagsNames;
       crtAct->studentsNames=_studentsNames;
       crtAct->duration=_duration;
       crtAct->totalDuration=td;
       crtAct->active=_active;
       crtAct->computeNTotalStudents=_computeNTotalStudents;
       crtAct->nTotalStudents=_nTotalStudents;
       
       this->internalStructureComputed=false;
       setRulesModifiedAndOtherThings(this);
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool Rules::modifySubgroup ( const QString &  yearName,
const QString &  groupName,
const QString &  initialSubgroupName,
const QString &  finalSubgroupName,
int  finalNumberOfStudents 
)

Modifies this students subgroup (name, number of students) and takes care of all related activities and constraints.

Returns true on success, false on failure (if not found)

Definition at line 3540 of file rules.cpp.

{
       StudentsSet* _initialSet=searchStudentsSet(initialSubgroupName);
       assert(_initialSet!=NULL);
       int _initialNumberOfStudents=_initialSet->numberOfStudents;

       QString _initialSubgroupName=initialSubgroupName;

       assert(searchSubgroup(yearName, groupName, _initialSubgroupName)>=0);
       StudentsSet* _ss=searchStudentsSet(finalSubgroupName);
       assert(_ss==NULL || _initialSubgroupName==finalSubgroupName);

       StudentsYear* sty=this->yearsList.at(this->searchYear(yearName));
       assert(sty);
       StudentsGroup* stg=sty->groupsList.at(this->searchGroup(yearName, groupName));
       assert(stg);

       StudentsSubgroup* sts=NULL;
       for(int i=0; i<stg->subgroupsList.size(); i++){
              sts=stg->subgroupsList[i];

              if(sts->name==_initialSubgroupName){
                     sts->name=finalSubgroupName;
                     sts->numberOfStudents=finalNumberOfStudents;
                     break;
              }
       }
       assert(sts);

       if(_ss!=NULL){ //In case it only changes the number of students, make the same number of students in all subgroups with this name
              assert(_initialSubgroupName==finalSubgroupName);
              foreach(StudentsYear* year, yearsList)
                     foreach(StudentsGroup* group, year->groupsList)
                            foreach(StudentsSubgroup* subgroup, group->subgroupsList)
                                   if(subgroup->name==finalSubgroupName)
                                          subgroup->numberOfStudents=finalNumberOfStudents;
       }

       //TODO: improve this part
       for(int i=0; i<this->activitiesList.size(); i++)
              this->activitiesList[i]->renameStudents(*this, _initialSubgroupName, finalSubgroupName, _initialNumberOfStudents, finalNumberOfStudents);

       for(int i=0; i<this->timeConstraintsList.size(); i++){
              TimeConstraint* ctr=this->timeConstraintsList[i];

              if(ctr->type==CONSTRAINT_STUDENTS_SET_NOT_AVAILABLE_TIMES){
                     ConstraintStudentsSetNotAvailableTimes* crt_constraint=(ConstraintStudentsSetNotAvailableTimes*)ctr;
                     if(_initialSubgroupName == crt_constraint->students)
                            crt_constraint->students=finalSubgroupName;
              }
              else if(ctr->type==CONSTRAINT_STUDENTS_SET_MAX_HOURS_DAILY){
                     ConstraintStudentsSetMaxHoursDaily* crt_constraint=(ConstraintStudentsSetMaxHoursDaily*)ctr;
                     if(_initialSubgroupName == crt_constraint->students)
                            crt_constraint->students=finalSubgroupName;
              }
              else if(ctr->type==CONSTRAINT_STUDENTS_SET_INTERVAL_MAX_DAYS_PER_WEEK){
                     ConstraintStudentsSetIntervalMaxDaysPerWeek* crt_constraint=(ConstraintStudentsSetIntervalMaxDaysPerWeek*)ctr;
                     if(_initialSubgroupName == crt_constraint->students)
                            crt_constraint->students=finalSubgroupName;
              }
              else if(ctr->type==CONSTRAINT_STUDENTS_SET_MAX_HOURS_CONTINUOUSLY){
                     ConstraintStudentsSetMaxHoursContinuously* crt_constraint=(ConstraintStudentsSetMaxHoursContinuously*)ctr;
                     if(_initialSubgroupName == crt_constraint->students)
                            crt_constraint->students=finalSubgroupName;
              }
              else if(ctr->type==CONSTRAINT_STUDENTS_SET_ACTIVITY_TAG_MAX_HOURS_CONTINUOUSLY){
                     ConstraintStudentsSetActivityTagMaxHoursContinuously* crt_constraint=(ConstraintStudentsSetActivityTagMaxHoursContinuously*)ctr;
                     if(_initialSubgroupName == crt_constraint->students)
                            crt_constraint->students=finalSubgroupName;
              }
              else if(ctr->type==CONSTRAINT_STUDENTS_SET_ACTIVITY_TAG_MAX_HOURS_DAILY){
                     ConstraintStudentsSetActivityTagMaxHoursDaily* crt_constraint=(ConstraintStudentsSetActivityTagMaxHoursDaily*)ctr;
                     if(_initialSubgroupName == crt_constraint->students)
                            crt_constraint->students=finalSubgroupName;
              }
              else if(ctr->type==CONSTRAINT_STUDENTS_SET_MIN_HOURS_DAILY){
                     ConstraintStudentsSetMinHoursDaily* crt_constraint=(ConstraintStudentsSetMinHoursDaily*)ctr;
                     if(_initialSubgroupName == crt_constraint->students)
                            crt_constraint->students=finalSubgroupName;
              }
              else if(ctr->type==CONSTRAINT_STUDENTS_SET_EARLY_MAX_BEGINNINGS_AT_SECOND_HOUR){
                     ConstraintStudentsSetEarlyMaxBeginningsAtSecondHour* crt_constraint=(ConstraintStudentsSetEarlyMaxBeginningsAtSecondHour*)ctr;
                     if(_initialSubgroupName == crt_constraint->students)
                            crt_constraint->students=finalSubgroupName;
              }
              else if(ctr->type==CONSTRAINT_STUDENTS_SET_MAX_GAPS_PER_WEEK){
                     ConstraintStudentsSetMaxGapsPerWeek* crt_constraint=(ConstraintStudentsSetMaxGapsPerWeek*)ctr;
                     if(_initialSubgroupName == crt_constraint->students)
                            crt_constraint->students=finalSubgroupName;
              }
              else if(ctr->type==CONSTRAINT_STUDENTS_SET_MAX_GAPS_PER_DAY){
                     ConstraintStudentsSetMaxGapsPerDay* crt_constraint=(ConstraintStudentsSetMaxGapsPerDay*)ctr;
                     if(_initialSubgroupName == crt_constraint->students)
                            crt_constraint->students=finalSubgroupName;
              }
              else if(ctr->type==CONSTRAINT_ACTIVITIES_PREFERRED_TIME_SLOTS){
                     ConstraintActivitiesPreferredTimeSlots* crt_constraint=(ConstraintActivitiesPreferredTimeSlots*)ctr;
                     if(_initialSubgroupName == crt_constraint->p_studentsName)
                            crt_constraint->p_studentsName=finalSubgroupName;
              }
              else if(ctr->type==CONSTRAINT_ACTIVITIES_PREFERRED_STARTING_TIMES){
                     ConstraintActivitiesPreferredStartingTimes* crt_constraint=(ConstraintActivitiesPreferredStartingTimes*)ctr;
                     if(_initialSubgroupName == crt_constraint->studentsName)
                            crt_constraint->studentsName=finalSubgroupName;
              }
              else if(ctr->type==CONSTRAINT_ACTIVITIES_END_STUDENTS_DAY){
                     ConstraintActivitiesEndStudentsDay* crt_constraint=(ConstraintActivitiesEndStudentsDay*)ctr;
                     if(_initialSubgroupName == crt_constraint->studentsName)
                            crt_constraint->studentsName=finalSubgroupName;
              }
              else if(ctr->type==CONSTRAINT_SUBACTIVITIES_PREFERRED_TIME_SLOTS){
                     ConstraintSubactivitiesPreferredTimeSlots* crt_constraint=(ConstraintSubactivitiesPreferredTimeSlots*)ctr;
                     if(_initialSubgroupName == crt_constraint->p_studentsName)
                            crt_constraint->p_studentsName=finalSubgroupName;
              }
              else if(ctr->type==CONSTRAINT_SUBACTIVITIES_PREFERRED_STARTING_TIMES){
                     ConstraintSubactivitiesPreferredStartingTimes* crt_constraint=(ConstraintSubactivitiesPreferredStartingTimes*)ctr;
                     if(_initialSubgroupName == crt_constraint->studentsName)
                            crt_constraint->studentsName=finalSubgroupName;
              }
       }

       for(int i=0; i<this->spaceConstraintsList.size(); i++){
              SpaceConstraint* ctr=this->spaceConstraintsList[i];

              if(ctr->type==CONSTRAINT_STUDENTS_SET_HOME_ROOM){
                     ConstraintStudentsSetHomeRoom* crt_constraint=(ConstraintStudentsSetHomeRoom*)ctr;
                     if(_initialSubgroupName == crt_constraint->studentsName)
                            crt_constraint->studentsName=finalSubgroupName;
              }
              else if(ctr->type==CONSTRAINT_STUDENTS_SET_HOME_ROOMS){
                     ConstraintStudentsSetHomeRooms* crt_constraint=(ConstraintStudentsSetHomeRooms*)ctr;
                     if(_initialSubgroupName == crt_constraint->studentsName)
                            crt_constraint->studentsName=finalSubgroupName;
              }
              else if(ctr->type==CONSTRAINT_STUDENTS_SET_MAX_BUILDING_CHANGES_PER_DAY){
                     ConstraintStudentsSetMaxBuildingChangesPerDay* crt_constraint=(ConstraintStudentsSetMaxBuildingChangesPerDay*)ctr;
                     if(_initialSubgroupName == crt_constraint->studentsName)
                            crt_constraint->studentsName=finalSubgroupName;
              }
              else if(ctr->type==CONSTRAINT_STUDENTS_SET_MAX_BUILDING_CHANGES_PER_WEEK){
                     ConstraintStudentsSetMaxBuildingChangesPerWeek* crt_constraint=(ConstraintStudentsSetMaxBuildingChangesPerWeek*)ctr;
                     if(_initialSubgroupName == crt_constraint->studentsName)
                            crt_constraint->studentsName=finalSubgroupName;
              }
              else if(ctr->type==CONSTRAINT_STUDENTS_SET_MIN_GAPS_BETWEEN_BUILDING_CHANGES){
                     ConstraintStudentsSetMinGapsBetweenBuildingChanges* crt_constraint=(ConstraintStudentsSetMinGapsBetweenBuildingChanges*)ctr;
                     if(_initialSubgroupName == crt_constraint->studentsName)
                            crt_constraint->studentsName=finalSubgroupName;
              }
       }

       this->internalStructureComputed=false;
       setRulesModifiedAndOtherThings(this);

       return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool Rules::modifySubject ( const QString &  initialSubjectName,
const QString &  finalSubjectName 
)

Modifies (renames) this subject and takes care of all related activities and constraints.

Returns true on success, false on failure (if not found)

Definition at line 1618 of file rules.cpp.

{
       assert(this->searchSubject(finalSubjectName)==-1);
       assert(this->searchSubject(initialSubjectName)>=0);

       //check the activities first
       for(int i=0; i<this->activitiesList.size(); i++){
              Activity* act=this->activitiesList[i];

              if( act->subjectName == initialSubjectName)
                     act->subjectName=finalSubjectName;
       }
       
       //modify the time constraints related to this subject
       for(int i=0; i<this->timeConstraintsList.size(); i++){
              TimeConstraint* ctr=this->timeConstraintsList[i];

              if(ctr->type==CONSTRAINT_ACTIVITIES_PREFERRED_TIME_SLOTS){
                     ConstraintActivitiesPreferredTimeSlots* crt_constraint=(ConstraintActivitiesPreferredTimeSlots*)ctr;
                     if(initialSubjectName == crt_constraint->p_subjectName)
                            crt_constraint->p_subjectName=finalSubjectName;
              }
       }

       //modify the time constraints related to this subject
       for(int i=0; i<this->timeConstraintsList.size(); i++){
              TimeConstraint* ctr=this->timeConstraintsList[i];

              if(ctr->type==CONSTRAINT_ACTIVITIES_PREFERRED_STARTING_TIMES){
                     ConstraintActivitiesPreferredStartingTimes* crt_constraint=(ConstraintActivitiesPreferredStartingTimes*)ctr;
                     if(initialSubjectName == crt_constraint->subjectName)
                            crt_constraint->subjectName=finalSubjectName;
              }
       }

       //modify the time constraints related to this subject
       for(int i=0; i<this->timeConstraintsList.size(); i++){
              TimeConstraint* ctr=this->timeConstraintsList[i];

              if(ctr->type==CONSTRAINT_ACTIVITIES_END_STUDENTS_DAY){
                     ConstraintActivitiesEndStudentsDay* crt_constraint=(ConstraintActivitiesEndStudentsDay*)ctr;
                     if(initialSubjectName == crt_constraint->subjectName)
                            crt_constraint->subjectName=finalSubjectName;
              }
       }

       //modify the time constraints related to this subject
       for(int i=0; i<this->timeConstraintsList.size(); i++){
              TimeConstraint* ctr=this->timeConstraintsList[i];

              if(ctr->type==CONSTRAINT_SUBACTIVITIES_PREFERRED_TIME_SLOTS){
                     ConstraintSubactivitiesPreferredTimeSlots* crt_constraint=(ConstraintSubactivitiesPreferredTimeSlots*)ctr;
                     if(initialSubjectName == crt_constraint->p_subjectName)
                            crt_constraint->p_subjectName=finalSubjectName;
              }
       }

       //modify the time constraints related to this subject
       for(int i=0; i<this->timeConstraintsList.size(); i++){
              TimeConstraint* ctr=this->timeConstraintsList[i];

              if(ctr->type==CONSTRAINT_SUBACTIVITIES_PREFERRED_STARTING_TIMES){
                     ConstraintSubactivitiesPreferredStartingTimes* crt_constraint=(ConstraintSubactivitiesPreferredStartingTimes*)ctr;
                     if(initialSubjectName == crt_constraint->subjectName)
                            crt_constraint->subjectName=finalSubjectName;
              }
       }

       //modify the space constraints related to this subject
       for(int i=0; i<this->spaceConstraintsList.size(); i++){
              SpaceConstraint* ctr=this->spaceConstraintsList[i];

              if(ctr->type==CONSTRAINT_SUBJECT_PREFERRED_ROOM){
                     ConstraintSubjectPreferredRoom* c=(ConstraintSubjectPreferredRoom*)ctr;
                     if(c->subjectName == initialSubjectName)
                            c->subjectName=finalSubjectName;
              }
              else if(ctr->type==CONSTRAINT_SUBJECT_PREFERRED_ROOMS){
                     ConstraintSubjectPreferredRooms* c=(ConstraintSubjectPreferredRooms*)ctr;
                     if(c->subjectName == initialSubjectName)
                            c->subjectName=finalSubjectName;
              }
              else if(ctr->type==CONSTRAINT_SUBJECT_ACTIVITY_TAG_PREFERRED_ROOM){
                     ConstraintSubjectActivityTagPreferredRoom* c=(ConstraintSubjectActivityTagPreferredRoom*)ctr;
                     if(c->subjectName == initialSubjectName)
                            c->subjectName=finalSubjectName;
              }
              else if(ctr->type==CONSTRAINT_SUBJECT_ACTIVITY_TAG_PREFERRED_ROOMS){
                     ConstraintSubjectActivityTagPreferredRooms* c=(ConstraintSubjectActivityTagPreferredRooms*)ctr;
                     if(c->subjectName == initialSubjectName)
                            c->subjectName=finalSubjectName;
              }
       }


       //rename the subject in the list
       int t=0;
       for(int i=0; i<this->subjectsList.size(); i++){
              Subject* sbj=this->subjectsList[i];

              if(sbj->name==initialSubjectName){
                     t++;
                     sbj->name=finalSubjectName;
              }
       }
       assert(t<=1);

       this->internalStructureComputed=false;
       setRulesModifiedAndOtherThings(this);

       return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool Rules::modifyTeacher ( const QString &  initialTeacherName,
const QString &  finalTeacherName 
)

Modifies (renames) this teacher and takes care of all related activities and constraints.

Returns true on success, false on failure (if not found)

Definition at line 1189 of file rules.cpp.

{
       assert(this->searchTeacher(finalTeacherName)==-1);
       assert(this->searchTeacher(initialTeacherName)>=0);

       //TODO: improve this part
       for(int i=0; i<this->activitiesList.size(); i++)
              this->activitiesList.at(i)->renameTeacher(initialTeacherName, finalTeacherName);

       for(int i=0; i<this->timeConstraintsList.size(); i++){
              TimeConstraint* ctr=this->timeConstraintsList[i];       

              if(ctr->type==CONSTRAINT_TEACHER_NOT_AVAILABLE_TIMES){
                     ConstraintTeacherNotAvailableTimes* crt_constraint=(ConstraintTeacherNotAvailableTimes*)ctr;
                     if(initialTeacherName == crt_constraint->teacher)
                            crt_constraint->teacher=finalTeacherName;
              }
       }

       for(int i=0; i<this->timeConstraintsList.size(); i++){
              TimeConstraint* ctr=this->timeConstraintsList[i];       

              if(ctr->type==CONSTRAINT_TEACHER_MAX_GAPS_PER_WEEK){
                     ConstraintTeacherMaxGapsPerWeek* crt_constraint=(ConstraintTeacherMaxGapsPerWeek*)ctr;
                     if(initialTeacherName == crt_constraint->teacherName)
                            crt_constraint->teacherName=finalTeacherName;
              }
       }

       for(int i=0; i<this->timeConstraintsList.size(); i++){
              TimeConstraint* ctr=this->timeConstraintsList[i];       

              if(ctr->type==CONSTRAINT_TEACHER_MAX_GAPS_PER_DAY){
                     ConstraintTeacherMaxGapsPerDay* crt_constraint=(ConstraintTeacherMaxGapsPerDay*)ctr;
                     if(initialTeacherName == crt_constraint->teacherName)
                            crt_constraint->teacherName=finalTeacherName;
              }
       }

       for(int i=0; i<this->timeConstraintsList.size(); i++){
              TimeConstraint* ctr=this->timeConstraintsList[i];       

              if(ctr->type==CONSTRAINT_TEACHER_MAX_HOURS_DAILY){
                     ConstraintTeacherMaxHoursDaily* crt_constraint=(ConstraintTeacherMaxHoursDaily*)ctr;
                     if(initialTeacherName == crt_constraint->teacherName)
                            crt_constraint->teacherName=finalTeacherName;
              }
       }

       for(int i=0; i<this->timeConstraintsList.size(); i++){
              TimeConstraint* ctr=this->timeConstraintsList[i];       

              if(ctr->type==CONSTRAINT_TEACHER_MAX_HOURS_CONTINUOUSLY){
                     ConstraintTeacherMaxHoursContinuously* crt_constraint=(ConstraintTeacherMaxHoursContinuously*)ctr;
                     if(initialTeacherName == crt_constraint->teacherName)
                            crt_constraint->teacherName=finalTeacherName;
              }
       }

       for(int i=0; i<this->timeConstraintsList.size(); i++){
              TimeConstraint* ctr=this->timeConstraintsList[i];       

              if(ctr->type==CONSTRAINT_TEACHER_ACTIVITY_TAG_MAX_HOURS_CONTINUOUSLY){
                     ConstraintTeacherActivityTagMaxHoursContinuously* crt_constraint=(ConstraintTeacherActivityTagMaxHoursContinuously*)ctr;
                     if(initialTeacherName == crt_constraint->teacherName)
                            crt_constraint->teacherName=finalTeacherName;
              }
       }

       for(int i=0; i<this->timeConstraintsList.size(); i++){
              TimeConstraint* ctr=this->timeConstraintsList[i];       

              if(ctr->type==CONSTRAINT_TEACHER_ACTIVITY_TAG_MAX_HOURS_DAILY){
                     ConstraintTeacherActivityTagMaxHoursDaily* crt_constraint=(ConstraintTeacherActivityTagMaxHoursDaily*)ctr;
                     if(initialTeacherName == crt_constraint->teacherName)
                            crt_constraint->teacherName=finalTeacherName;
              }
       }

       for(int i=0; i<this->timeConstraintsList.size(); i++){
              TimeConstraint* ctr=this->timeConstraintsList[i];       

              if(ctr->type==CONSTRAINT_TEACHER_MIN_HOURS_DAILY){
                     ConstraintTeacherMinHoursDaily* crt_constraint=(ConstraintTeacherMinHoursDaily*)ctr;
                     if(initialTeacherName == crt_constraint->teacherName)
                            crt_constraint->teacherName=finalTeacherName;
              }
       }

       for(int i=0; i<this->timeConstraintsList.size(); i++){
              TimeConstraint* ctr=this->timeConstraintsList[i];       

              if(ctr->type==CONSTRAINT_TEACHER_MAX_DAYS_PER_WEEK){
                     ConstraintTeacherMaxDaysPerWeek* crt_constraint=(ConstraintTeacherMaxDaysPerWeek*)ctr;
                     if(initialTeacherName == crt_constraint->teacherName)
                            crt_constraint->teacherName=finalTeacherName;
              }
       }
       
       for(int i=0; i<this->timeConstraintsList.size(); i++){
              TimeConstraint* ctr=this->timeConstraintsList[i];       

              if(ctr->type==CONSTRAINT_TEACHER_MIN_DAYS_PER_WEEK){
                     ConstraintTeacherMinDaysPerWeek* crt_constraint=(ConstraintTeacherMinDaysPerWeek*)ctr;
                     if(initialTeacherName == crt_constraint->teacherName)
                            crt_constraint->teacherName=finalTeacherName;
              }
       }
       
       for(int i=0; i<this->timeConstraintsList.size(); i++){
              TimeConstraint* ctr=this->timeConstraintsList[i];       

              if(ctr->type==CONSTRAINT_TEACHER_INTERVAL_MAX_DAYS_PER_WEEK){
                     ConstraintTeacherIntervalMaxDaysPerWeek* crt_constraint=(ConstraintTeacherIntervalMaxDaysPerWeek*)ctr;
                     if(initialTeacherName == crt_constraint->teacherName)
                            crt_constraint->teacherName=finalTeacherName;
              }
       }
       
       for(int i=0; i<this->timeConstraintsList.size(); i++){
              TimeConstraint* ctr=this->timeConstraintsList[i];       

              if(ctr->type==CONSTRAINT_ACTIVITIES_PREFERRED_TIME_SLOTS){
                     ConstraintActivitiesPreferredTimeSlots* crt_constraint=(ConstraintActivitiesPreferredTimeSlots*)ctr;
                     if(initialTeacherName == crt_constraint->p_teacherName)
                            crt_constraint->p_teacherName=finalTeacherName;
              }
       }
       
       for(int i=0; i<this->timeConstraintsList.size(); i++){
              TimeConstraint* ctr=this->timeConstraintsList[i];       

              if(ctr->type==CONSTRAINT_ACTIVITIES_PREFERRED_STARTING_TIMES){
                     ConstraintActivitiesPreferredStartingTimes* crt_constraint=(ConstraintActivitiesPreferredStartingTimes*)ctr;
                     if(initialTeacherName == crt_constraint->teacherName)
                            crt_constraint->teacherName=finalTeacherName;
              }
       }
       
       for(int i=0; i<this->timeConstraintsList.size(); i++){
              TimeConstraint* ctr=this->timeConstraintsList[i];       

              if(ctr->type==CONSTRAINT_ACTIVITIES_END_STUDENTS_DAY){
                     ConstraintActivitiesEndStudentsDay* crt_constraint=(ConstraintActivitiesEndStudentsDay*)ctr;
                     if(initialTeacherName == crt_constraint->teacherName)
                            crt_constraint->teacherName=finalTeacherName;
              }
       }
       
       for(int i=0; i<this->timeConstraintsList.size(); i++){
              TimeConstraint* ctr=this->timeConstraintsList[i];       

              if(ctr->type==CONSTRAINT_SUBACTIVITIES_PREFERRED_TIME_SLOTS){
                     ConstraintSubactivitiesPreferredTimeSlots* crt_constraint=(ConstraintSubactivitiesPreferredTimeSlots*)ctr;
                     if(initialTeacherName == crt_constraint->p_teacherName)
                            crt_constraint->p_teacherName=finalTeacherName;
              }
       }
       
       for(int i=0; i<this->timeConstraintsList.size(); i++){
              TimeConstraint* ctr=this->timeConstraintsList[i];       

              if(ctr->type==CONSTRAINT_SUBACTIVITIES_PREFERRED_STARTING_TIMES){
                     ConstraintSubactivitiesPreferredStartingTimes* crt_constraint=(ConstraintSubactivitiesPreferredStartingTimes*)ctr;
                     if(initialTeacherName == crt_constraint->teacherName)
                            crt_constraint->teacherName=finalTeacherName;
              }
       }
       

       for(int i=0; i<this->spaceConstraintsList.size(); i++){
              SpaceConstraint* ctr=this->spaceConstraintsList[i];     

              if(ctr->type==CONSTRAINT_TEACHER_HOME_ROOM){
                     ConstraintTeacherHomeRoom* crt_constraint=(ConstraintTeacherHomeRoom*)ctr;
                     if(initialTeacherName == crt_constraint->teacherName)
                            crt_constraint->teacherName=finalTeacherName;
              }
       }
       
       for(int i=0; i<this->spaceConstraintsList.size(); i++){
              SpaceConstraint* ctr=this->spaceConstraintsList[i];     

              if(ctr->type==CONSTRAINT_TEACHER_HOME_ROOMS){
                     ConstraintTeacherHomeRooms* crt_constraint=(ConstraintTeacherHomeRooms*)ctr;
                     if(initialTeacherName == crt_constraint->teacherName)
                            crt_constraint->teacherName=finalTeacherName;
              }
       }
       
       for(int i=0; i<this->spaceConstraintsList.size(); i++){
              SpaceConstraint* ctr=this->spaceConstraintsList[i];     

              if(ctr->type==CONSTRAINT_TEACHER_MAX_BUILDING_CHANGES_PER_DAY){
                     ConstraintTeacherMaxBuildingChangesPerDay* crt_constraint=(ConstraintTeacherMaxBuildingChangesPerDay*)ctr;
                     if(initialTeacherName == crt_constraint->teacherName)
                            crt_constraint->teacherName=finalTeacherName;
              }
       }
       for(int i=0; i<this->spaceConstraintsList.size(); i++){
              SpaceConstraint* ctr=this->spaceConstraintsList[i];     

              if(ctr->type==CONSTRAINT_TEACHER_MAX_BUILDING_CHANGES_PER_WEEK){
                     ConstraintTeacherMaxBuildingChangesPerWeek* crt_constraint=(ConstraintTeacherMaxBuildingChangesPerWeek*)ctr;
                     if(initialTeacherName == crt_constraint->teacherName)
                            crt_constraint->teacherName=finalTeacherName;
              }
       }
       for(int i=0; i<this->spaceConstraintsList.size(); i++){
              SpaceConstraint* ctr=this->spaceConstraintsList[i];     

              if(ctr->type==CONSTRAINT_TEACHER_MIN_GAPS_BETWEEN_BUILDING_CHANGES){
                     ConstraintTeacherMinGapsBetweenBuildingChanges* crt_constraint=(ConstraintTeacherMinGapsBetweenBuildingChanges*)ctr;
                     if(initialTeacherName == crt_constraint->teacherName)
                            crt_constraint->teacherName=finalTeacherName;
              }
       }
       


       int t=0;
       for(int i=0; i<this->teachersList.size(); i++){
              Teacher* tch=this->teachersList[i];

              if(tch->name==initialTeacherName){
                     tch->name=finalTeacherName;
                     t++;
              }
       }
       assert(t<=1);

       this->internalStructureComputed=false;
       setRulesModifiedAndOtherThings(this);

       if(t==0)
              return false;
       else
              return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool Rules::modifyYear ( const QString &  initialYearName,
const QString &  finalYearName,
int  finalNumberOfStudents 
)

Modifies this students year (name, number of students) and takes care of all related activities and constraints.

Returns true on success, false on failure (if not found)

Definition at line 2582 of file rules.cpp.

{
       StudentsSet* _initialSet=searchStudentsSet(initialYearName);
       assert(_initialSet!=NULL);
       int _initialNumberOfStudents=_initialSet->numberOfStudents;

       QString _initialYearName=initialYearName;

       assert(searchYear(_initialYearName)>=0);
       StudentsSet* _ss=searchStudentsSet(finalYearName);
       assert(_ss==NULL || _initialYearName==finalYearName);

       for(int i=0; i<this->activitiesList.size(); i++){
              Activity* act=this->activitiesList[i];
              act->renameStudents(*this, _initialYearName, finalYearName, _initialNumberOfStudents, finalNumberOfStudents);
       }

       for(int i=0; i<this->timeConstraintsList.size(); i++){
              TimeConstraint* ctr=this->timeConstraintsList[i];

              if(ctr->type==CONSTRAINT_STUDENTS_SET_NOT_AVAILABLE_TIMES){
                     ConstraintStudentsSetNotAvailableTimes* crt_constraint=(ConstraintStudentsSetNotAvailableTimes*)ctr;
                     if(_initialYearName == crt_constraint->students)
                            crt_constraint->students=finalYearName;
              }
              else if(ctr->type==CONSTRAINT_STUDENTS_SET_MAX_HOURS_DAILY){
                     ConstraintStudentsSetMaxHoursDaily* crt_constraint=(ConstraintStudentsSetMaxHoursDaily*)ctr;
                     if(_initialYearName == crt_constraint->students)
                            crt_constraint->students=finalYearName;
              }
              else if(ctr->type==CONSTRAINT_STUDENTS_SET_INTERVAL_MAX_DAYS_PER_WEEK){
                     ConstraintStudentsSetIntervalMaxDaysPerWeek* crt_constraint=(ConstraintStudentsSetIntervalMaxDaysPerWeek*)ctr;
                     if(_initialYearName == crt_constraint->students)
                            crt_constraint->students=finalYearName;
              }
              else if(ctr->type==CONSTRAINT_STUDENTS_SET_MAX_HOURS_CONTINUOUSLY){
                     ConstraintStudentsSetMaxHoursContinuously* crt_constraint=(ConstraintStudentsSetMaxHoursContinuously*)ctr;
                     if(_initialYearName == crt_constraint->students)
                            crt_constraint->students=finalYearName;
              }
              else if(ctr->type==CONSTRAINT_STUDENTS_SET_ACTIVITY_TAG_MAX_HOURS_CONTINUOUSLY){
                     ConstraintStudentsSetActivityTagMaxHoursContinuously* crt_constraint=(ConstraintStudentsSetActivityTagMaxHoursContinuously*)ctr;
                     if(_initialYearName == crt_constraint->students)
                            crt_constraint->students=finalYearName;
              }
              else if(ctr->type==CONSTRAINT_STUDENTS_SET_ACTIVITY_TAG_MAX_HOURS_DAILY){
                     ConstraintStudentsSetActivityTagMaxHoursDaily* crt_constraint=(ConstraintStudentsSetActivityTagMaxHoursDaily*)ctr;
                     if(_initialYearName == crt_constraint->students)
                            crt_constraint->students=finalYearName;
              }
              else if(ctr->type==CONSTRAINT_STUDENTS_SET_MIN_HOURS_DAILY){
                     ConstraintStudentsSetMinHoursDaily* crt_constraint=(ConstraintStudentsSetMinHoursDaily*)ctr;
                     if(_initialYearName == crt_constraint->students)
                            crt_constraint->students=finalYearName;
              }
              else if(ctr->type==CONSTRAINT_STUDENTS_SET_EARLY_MAX_BEGINNINGS_AT_SECOND_HOUR){
                     ConstraintStudentsSetEarlyMaxBeginningsAtSecondHour* crt_constraint=(ConstraintStudentsSetEarlyMaxBeginningsAtSecondHour*)ctr;
                     if(_initialYearName == crt_constraint->students)
                            crt_constraint->students=finalYearName;
              }
              else if(ctr->type==CONSTRAINT_STUDENTS_SET_MAX_GAPS_PER_WEEK){
                     ConstraintStudentsSetMaxGapsPerWeek* crt_constraint=(ConstraintStudentsSetMaxGapsPerWeek*)ctr;
                     if(_initialYearName == crt_constraint->students)
                            crt_constraint->students=finalYearName;
              }
              else if(ctr->type==CONSTRAINT_STUDENTS_SET_MAX_GAPS_PER_DAY){
                     ConstraintStudentsSetMaxGapsPerDay* crt_constraint=(ConstraintStudentsSetMaxGapsPerDay*)ctr;
                     if(_initialYearName == crt_constraint->students)
                            crt_constraint->students=finalYearName;
              }
              else if(ctr->type==CONSTRAINT_ACTIVITIES_PREFERRED_TIME_SLOTS){
                     ConstraintActivitiesPreferredTimeSlots* crt_constraint=(ConstraintActivitiesPreferredTimeSlots*)ctr;
                     if(_initialYearName == crt_constraint->p_studentsName)
                            crt_constraint->p_studentsName=finalYearName;
              }
              else if(ctr->type==CONSTRAINT_ACTIVITIES_PREFERRED_STARTING_TIMES){
                     ConstraintActivitiesPreferredStartingTimes* crt_constraint=(ConstraintActivitiesPreferredStartingTimes*)ctr;
                     if(_initialYearName == crt_constraint->studentsName)
                            crt_constraint->studentsName=finalYearName;
              }
              else if(ctr->type==CONSTRAINT_ACTIVITIES_END_STUDENTS_DAY){
                     ConstraintActivitiesEndStudentsDay* crt_constraint=(ConstraintActivitiesEndStudentsDay*)ctr;
                     if(_initialYearName == crt_constraint->studentsName)
                            crt_constraint->studentsName=finalYearName;
              }
              else if(ctr->type==CONSTRAINT_SUBACTIVITIES_PREFERRED_TIME_SLOTS){
                     ConstraintSubactivitiesPreferredTimeSlots* crt_constraint=(ConstraintSubactivitiesPreferredTimeSlots*)ctr;
                     if(_initialYearName == crt_constraint->p_studentsName)
                            crt_constraint->p_studentsName=finalYearName;
              }
              else if(ctr->type==CONSTRAINT_SUBACTIVITIES_PREFERRED_STARTING_TIMES){
                     ConstraintSubactivitiesPreferredStartingTimes* crt_constraint=(ConstraintSubactivitiesPreferredStartingTimes*)ctr;
                     if(_initialYearName == crt_constraint->studentsName)
                            crt_constraint->studentsName=finalYearName;
              }
       }

       for(int i=0; i<this->spaceConstraintsList.size(); i++){
              SpaceConstraint* ctr=this->spaceConstraintsList[i];

              if(ctr->type==CONSTRAINT_STUDENTS_SET_HOME_ROOM){
                     ConstraintStudentsSetHomeRoom* crt_constraint=(ConstraintStudentsSetHomeRoom*)ctr;
                     if(_initialYearName == crt_constraint->studentsName)
                            crt_constraint->studentsName=finalYearName;
              }
              else if(ctr->type==CONSTRAINT_STUDENTS_SET_HOME_ROOMS){
                     ConstraintStudentsSetHomeRooms* crt_constraint=(ConstraintStudentsSetHomeRooms*)ctr;
                     if(_initialYearName == crt_constraint->studentsName)
                            crt_constraint->studentsName=finalYearName;
              }
              else if(ctr->type==CONSTRAINT_STUDENTS_SET_MAX_BUILDING_CHANGES_PER_DAY){
                     ConstraintStudentsSetMaxBuildingChangesPerDay* crt_constraint=(ConstraintStudentsSetMaxBuildingChangesPerDay*)ctr;
                     if(_initialYearName == crt_constraint->studentsName)
                            crt_constraint->studentsName=finalYearName;
              }
              else if(ctr->type==CONSTRAINT_STUDENTS_SET_MAX_BUILDING_CHANGES_PER_WEEK){
                     ConstraintStudentsSetMaxBuildingChangesPerWeek* crt_constraint=(ConstraintStudentsSetMaxBuildingChangesPerWeek*)ctr;
                     if(_initialYearName == crt_constraint->studentsName)
                            crt_constraint->studentsName=finalYearName;
              }
              else if(ctr->type==CONSTRAINT_STUDENTS_SET_MIN_GAPS_BETWEEN_BUILDING_CHANGES){
                     ConstraintStudentsSetMinGapsBetweenBuildingChanges* crt_constraint=(ConstraintStudentsSetMinGapsBetweenBuildingChanges*)ctr;
                     if(_initialYearName == crt_constraint->studentsName)
                            crt_constraint->studentsName=finalYearName;
              }
       }

       int t=0;
       
       for(int i=0; i<this->yearsList.size(); i++){
              StudentsYear* sty=this->yearsList[i];
       
              if(sty->name==_initialYearName){
                     sty->name=finalYearName;
                     sty->numberOfStudents=finalNumberOfStudents;
                     t++;
                     
                     /*for(int j=0; j<sty->groupsList.size(); j++){
                            StudentsGroup* stg=sty->groupsList[j];

                            if(stg->name.right(11)==" WHOLE YEAR" && stg->name.left(stg->name.length()-11)==_initialYearName)
                                   this->modifyGroup(sty->name, stg->name, sty->name+" WHOLE YEAR", stg->numberOfStudents);
                     }*/
              }
       }
              
       assert(t<=1);

       this->internalStructureComputed=false;
       setRulesModifiedAndOtherThings(this);
       
       if(t==0)
              return false;
       else
              return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool Rules::read ( QWidget *  parent,
const QString &  filename,
bool  commandLine = false,
QString  commandLineDirectory = QString() 
)

Reads the rules from the xml input file "filename".

Returns true on success, false on failure (inexistent file or wrong format)

Definition at line 5300 of file rules.cpp.

{
       //bool reportWhole=true;

       QFile file(filename);
       if(!file.open(QIODevice::ReadOnly)){
              //cout<<"Could not open file - not existing or in use\n";
              QMessageBox::warning(parent, tr("FET warning"), tr("Could not open file - not existing or in use"));
              return false;
       }
       //QDomDocument doc("xml_rules");
       QDomDocument doc;
       
       QString errorStr;
       int errorLine;
       int errorColumn;
       
       if(!doc.setContent(&file, true, &errorStr, &errorLine, &errorColumn)){
              QMessageBox::warning(parent, tr("FET warning"),
               tr("Could not read file - XML parse error at line %1, column %2:\n%3", "The error description is %3")
               .arg(errorLine)
               .arg(errorColumn)
               .arg(errorStr));
       
              file.close();
              return false;
       }
       file.close();


       if(!commandLine){
              //logging part
              QDir dir;
              bool t=true;
              if(!dir.exists(OUTPUT_DIR+FILE_SEP+"logs"))
                     t=dir.mkpath(OUTPUT_DIR+FILE_SEP+"logs");
              if(!t){
                     QMessageBox::warning(parent, tr("FET warning"), tr("Cannot create or use directory %1 - cannot continue").arg(QDir::toNativeSeparators(OUTPUT_DIR+FILE_SEP+"logs")));
                     return false;
              }
              assert(t);
       }
       else{
              QDir dir;
              bool t=true;
              if(!dir.exists(commandLineDirectory+"logs"))
                     t=dir.mkpath(commandLineDirectory+"logs");
              if(!t){
                     QMessageBox::warning(parent, tr("FET warning"), tr("Cannot create or use directory %1 - cannot continue").arg(QDir::toNativeSeparators(commandLineDirectory+"logs")));
                     return false;
              }
              assert(t);
       }
       
       FakeString xmlReadingLog;
       xmlReadingLog="";

       QDate dat=QDate::currentDate();
       QTime tim=QTime::currentTime();
       QLocale loc(FET_LANGUAGE);
       QString sTime=loc.toString(dat, QLocale::ShortFormat)+" "+loc.toString(tim, QLocale::ShortFormat);

       QString reducedXmlLog="";
       reducedXmlLog+="Log generated by FET "+FET_VERSION+" on "+sTime+"\n\n";
       QString shortFilename=filename.right(filename.length()-filename.lastIndexOf(FILE_SEP)-1);
       reducedXmlLog+="Reading file "+shortFilename+"\n";
       QFileInfo fileinfo(filename);
       reducedXmlLog+="Complete file name, including path: "+QDir::toNativeSeparators(fileinfo.absoluteFilePath())+"\n";
       reducedXmlLog+="\n";

       QString tmp;
       if(commandLine)
              tmp=commandLineDirectory+"logs"+FILE_SEP+XML_PARSING_LOG_FILENAME;
       else
              tmp=OUTPUT_DIR+FILE_SEP+"logs"+FILE_SEP+XML_PARSING_LOG_FILENAME;
       QFile file2(tmp);
       bool canWriteLogFile=true;
       if(!file2.open(QIODevice::WriteOnly)){
              QString s=tr("FET cannot open the log file %1 for writing. This might mean that you don't"
                     " have write permissions in this location. You can continue operation, but you might not be able to save the generated timetables"
                     " as html files").arg(QDir::toNativeSeparators(tmp))+
                     "\n\n"+tr("A solution is to remove that file (if it exists already) or set its permissions to allow writing")+
                     "\n\n"+tr("Please report possible bug");
              QMessageBox::critical(parent, tr("FET critical"), s);
              canWriteLogFile=false;
       }
       QTextStream logStream;
       if(canWriteLogFile){
              logStream.setDevice(&file2);
              logStream.setCodec("UTF-8");
              logStream.setGenerateByteOrderMark(true);
       }
       
       QDomElement elem1=doc.documentElement();
       xmlReadingLog+=" Found "+elem1.tagName()+" tag\n";
       bool okAbove3_12_17=true;
       bool version5AndAbove=false;
       bool warning=false;
       
       QString file_version;
       
       bool okfetTag;
       if(elem1.tagName()=="fet" || elem1.tagName()=="FET") //the new tag is fet, the old tag - FET
              okfetTag=true;
       else
              okfetTag=false;
       
       if(!okfetTag)
              okAbove3_12_17=false;
       else{
              assert(okAbove3_12_17==true);
              /*QDomDocumentType dt=doc.doctype();
              if(dt.isNull() || dt.name()!="FET")
                     okAbove3_12_17=false;
              else*/
              int filev[3], fetv[3];
              
              QDomAttr a=elem1.attributeNode("version");
              
              QString version=a.value();
              file_version=version;

              QRegExp fileVerReCap("^(\\d+)\\.(\\d+)\\.(\\d+)(.*)$");

              int tfile=fileVerReCap.indexIn(file_version);
              filev[0]=filev[1]=filev[2]=-1;
              if(tfile!=0){
                     QMessageBox::warning(parent, tr("FET warning"), tr("File contains a version numbering scheme which"
                     " is not matched by v.v.va (3 numbers separated by points, followed by any string a, which may be empty). File will be opened, but you are adviced"
                     " to check the version of the .fet file (in the beginning of the file). If this is a FET bug, please report it")+"\n\n"+
                     tr("If you are opening a file older than FET format version 5, it will be converted to latest FET data format"));
                     cout<<"Opened file version not matched by regexp"<<endl;
              }
              else{
                     bool ok;
                     filev[0]=fileVerReCap.cap(1).toInt(&ok);
                     assert(ok);
                     filev[1]=fileVerReCap.cap(2).toInt(&ok);
                     assert(ok);
                     filev[2]=fileVerReCap.cap(3).toInt(&ok);
                     assert(ok);
                     cout<<"Opened file version matched by regexp: major="<<filev[0]<<", minor="<<filev[1]<<", revision="<<filev[2];
                     cout<<", additional text="<<qPrintable(fileVerReCap.cap(4))<<"."<<endl;
              }
              
              QRegExp fetVerReCap("^(\\d+)\\.(\\d+)\\.(\\d+)(.*)$");

              int tfet=fetVerReCap.indexIn(FET_VERSION);
              fetv[0]=fetv[1]=fetv[2]=-1;
              if(tfet!=0){
                     QMessageBox::warning(parent, tr("FET warning"), tr("FET version does not respect the format v.v.va"
                     " (3 numbers separated by points, followed by any string a, which may be empty). This is probably a bug in FET - please report it"));
                     cout<<"FET version not matched by regexp"<<endl;
              }
              else{
                     bool ok;
                     fetv[0]=fetVerReCap.cap(1).toInt(&ok);
                     assert(ok);
                     fetv[1]=fetVerReCap.cap(2).toInt(&ok);
                     assert(ok);
                     fetv[2]=fetVerReCap.cap(3).toInt(&ok);
                     assert(ok);
                     cout<<"FET version matched by regexp: major="<<fetv[0]<<", minor="<<fetv[1]<<", revision="<<fetv[2];
                     cout<<", additional text="<<qPrintable(fetVerReCap.cap(4))<<"."<<endl;
              }
              
              if(filev[0]>=0 && fetv[0]>=0 && filev[1]>=0 && fetv[1]>=0 && filev[2]>=0 && fetv[2]>=0){
                     if(filev[0]>fetv[0] || (filev[0]==fetv[0] && filev[1]>fetv[1]) || (filev[0]==fetv[0]&&filev[1]==fetv[1]&&filev[2]>fetv[2])){
                            warning=true;
                     }
              }
              
              if(filev[0]>=5 || (filev[0]==-1 && filev[1]==-1 && filev[2]==-1))
              //if major is >= 5 or major cannot be read
                     version5AndAbove=true;
       }
       if(!okAbove3_12_17){
              cout<<"Invalid fet 3.12.17 or above"<<endl;
              file2.close();
              QMessageBox::warning(parent, tr("FET warning"), tr("File does not have a corresponding beginning tag - it should be %1 or %2. File is incorrect..."
                     "it cannot be opened").arg("fet").arg("FET"));
              return false;
       }
       
       if(!version5AndAbove){
              QMessageBox::warning(parent, tr("FET information"), 
               tr("Opening older file - it will be converted to latest format, automatically "
               "assigning weight percentages to constraints and dropping parity for activities. "
               "You are adviced to make a backup of your old file before saving in new format.\n\n"
               "Please note that the default weight percentage of constraints min days between activities "
               "will be 95% (mainly satisfied, not always) and 'force consecutive if same day' will be set to true "
               "(meaning that if the activities are in the same day, they will be placed continuously, in a bigger duration activity)"
               "If you want, you can modify this percent to be 100%, manually in the fet input file "
               "or from the interface"));
       }
       
       if(warning){
              QMessageBox::warning(parent, tr("FET information"), 
               tr("Opening a file generated with a newer version than your current FET software ... file will be opened but it is recommended to update your FET software to the latest version")
               +"\n\n"+tr("Your FET version: %1, file version: %2").arg(FET_VERSION).arg(file_version));
       }
       
       //Clear old rules, initialize new rules
       if(this->initialized)
              this->kill();
       this->init();
       
       this->nHoursPerDay=12;
       this->hoursOfTheDay[0]="08:00";
       this->hoursOfTheDay[1]="09:00";
       this->hoursOfTheDay[2]="10:00";
       this->hoursOfTheDay[3]="11:00";
       this->hoursOfTheDay[4]="12:00";
       this->hoursOfTheDay[5]="13:00";
       this->hoursOfTheDay[6]="14:00";
       this->hoursOfTheDay[7]="15:00";
       this->hoursOfTheDay[8]="16:00";
       this->hoursOfTheDay[9]="17:00";
       this->hoursOfTheDay[10]="18:00";
       this->hoursOfTheDay[11]="19:00";
       //this->hoursOfTheDay[12]="20:00";

       this->nDaysPerWeek=5;
       this->daysOfTheWeek[0] = tr("Monday");
       this->daysOfTheWeek[1] = tr("Tuesday");
       this->daysOfTheWeek[2] = tr("Wednesday");
       this->daysOfTheWeek[3] = tr("Thursday");
       this->daysOfTheWeek[4] = tr("Friday");

       this->institutionName=tr("Default institution");
       this->comments=tr("Default comments");

       bool skipDeprecatedConstraints=false;
       
       bool skipDuplicatedStudentsSets=false;
       
       for(QDomNode node2=elem1.firstChild(); !node2.isNull(); node2=node2.nextSibling()){
              QDomElement elem2=node2.toElement();
              if(elem2.isNull())
                     xmlReadingLog+="  Null node here\n";
              xmlReadingLog+="  Found "+elem2.tagName()+" tag\n";
              if(elem2.tagName()=="Institution_Name"){
                     this->institutionName=elem2.text();
                     xmlReadingLog+="  Found institution name="+this->institutionName+"\n";
                     reducedXmlLog+="Read institution name="+this->institutionName+"\n";
              }
              else if(elem2.tagName()=="Comments"){
                     this->comments=elem2.text();
                     xmlReadingLog+="  Found comments="+this->comments+"\n";
                     reducedXmlLog+="Read comments="+this->comments+"\n";
              }
              else if(elem2.tagName()=="Hours_List"){
                     int tmp=0;
                     for(QDomNode node3=elem2.firstChild(); !node3.isNull(); node3=node3.nextSibling()){
                            QDomElement elem3=node3.toElement();
                            if(elem3.isNull()){
                                   xmlReadingLog+="   Null node here\n";
                                   continue;
                            }
                            xmlReadingLog+="   Found "+elem3.tagName()+" tag\n";
                            if(elem3.tagName()=="Number"){
                                   this->nHoursPerDay=elem3.text().toInt();
                                   xmlReadingLog+="   Found the number of hours per day = "+
                                    CustomFETString::number(this->nHoursPerDay)+"\n";
                                   reducedXmlLog+="Added "+
                                    CustomFETString::number(this->nHoursPerDay)+" hours per day\n";
                                   assert(this->nHoursPerDay>0);
                            }
                            else if(elem3.tagName()=="Name"){
                                   this->hoursOfTheDay[tmp]=elem3.text();
                                   xmlReadingLog+="   Found hour "+this->hoursOfTheDay[tmp]+"\n";
                                   tmp++;
                            }
                     }
                     //don't do assert tmp == nHoursPerDay, because some older files contain also the end of day hour, so tmp==nHoursPerDay+1 in this case
              }
              else if(elem2.tagName()=="Days_List"){
                     int tmp=0;
                     for(QDomNode node3=elem2.firstChild(); !node3.isNull(); node3=node3.nextSibling()){
                            QDomElement elem3=node3.toElement();
                            if(elem3.isNull()){
                                   xmlReadingLog+="   Null node here\n";
                                   continue;
                            }
                            xmlReadingLog+="   Found "+elem3.tagName()+" tag\n";
                            if(elem3.tagName()=="Number"){
                                   this->nDaysPerWeek=elem3.text().toInt();
                                   xmlReadingLog+="   Found the number of days per week = "+
                                    CustomFETString::number(this->nDaysPerWeek)+"\n";
                                   reducedXmlLog+="Added "+
                                    CustomFETString::number(this->nDaysPerWeek)+" days per week\n";
                                   assert(this->nDaysPerWeek>0);
                            }
                            else if(elem3.tagName()=="Name"){
                                   this->daysOfTheWeek[tmp]=elem3.text();
                                   xmlReadingLog+="   Found day "+this->daysOfTheWeek[tmp]+"\n";
                                   tmp++;
                            }
                     }
                     assert(tmp==this->nDaysPerWeek);
              }
              else if(elem2.tagName()=="Teachers_List"){
                     QSet<QString> teachersRead;
              
                     int tmp=0;
                     for(QDomNode node3=elem2.firstChild(); !node3.isNull(); node3=node3.nextSibling()){
                            QDomElement elem3=node3.toElement();
                            if(elem3.isNull()){
                                   xmlReadingLog+="   Null node here\n";
                                   continue;
                            }
                            xmlReadingLog+="   Found "+elem3.tagName()+" tag\n";
                            if(elem3.tagName()=="Teacher"){
                                   Teacher* teacher=new Teacher();
                                   for(QDomNode node4=elem3.firstChild(); !node4.isNull(); node4=node4.nextSibling()){
                                          QDomElement elem4=node4.toElement();
                                          if(elem4.isNull()){
                                                 xmlReadingLog+="    Null node here\n";
                                                 continue;
                                          }
                                          xmlReadingLog+="    Found "+elem4.tagName()+" tag\n";
                                          if(elem4.tagName()=="Name"){
                                                 teacher->name=elem4.text();
                                                 xmlReadingLog+="    Read teacher name: "+teacher->name+"\n";
                                          }
                                   }
                                   bool tmp2=teachersRead.contains(teacher->name);
                                   if(tmp2){
                                          QMessageBox::warning(parent, tr("FET warning"),
                                           tr("Duplicate teacher %1 found - ignoring").arg(teacher->name));
                                          xmlReadingLog+="   Teacher not added - duplicate\n";
                                   }
                                   else{
                                          teachersRead.insert(teacher->name);
                                          this->addTeacherFast(teacher);
                                          tmp++;
                                          xmlReadingLog+="   Teacher added\n";
                                   }
                            }
                     }
                     assert(tmp==this->teachersList.size());
                     xmlReadingLog+="  Added "+CustomFETString::number(tmp)+" teachers\n";
                     reducedXmlLog+="Added "+CustomFETString::number(tmp)+" teachers\n";
              }
              else if(elem2.tagName()=="Subjects_List"){
                     QSet<QString> subjectsRead;
              
                     int tmp=0;
                     for(QDomNode node3=elem2.firstChild(); !node3.isNull(); node3=node3.nextSibling()){
                            QDomElement elem3=node3.toElement();
                            if(elem3.isNull()){
                                   xmlReadingLog+="   Null node here\n";
                                   continue;
                            }
                            xmlReadingLog+="   Found "+elem3.tagName()+" tag\n";
                            if(elem3.tagName()=="Subject"){
                                   Subject* subject=new Subject();
                                   for(QDomNode node4=elem3.firstChild(); !node4.isNull(); node4=node4.nextSibling()){
                                          QDomElement elem4=node4.toElement();
                                          if(elem4.isNull()){
                                                 xmlReadingLog+="    Null node here\n";
                                                 continue;
                                          }
                                          xmlReadingLog+="    Found "+elem4.tagName()+" tag\n";
                                          if(elem4.tagName()=="Name"){
                                                 subject->name=elem4.text();
                                                 xmlReadingLog+="    Read subject name: "+subject->name+"\n";
                                          }
                                   }
                                   bool tmp2=subjectsRead.contains(subject->name);
                                   if(tmp2){
                                          QMessageBox::warning(parent, tr("FET warning"),
                                           tr("Duplicate subject %1 found - ignoring").arg(subject->name));
                                          xmlReadingLog+="   Subject not added - duplicate\n";
                                   }
                                   else{
                                          subjectsRead.insert(subject->name);
                                          this->addSubjectFast(subject);
                                          tmp++;
                                          xmlReadingLog+="   Subject inserted\n";
                                   }
                            }
                     }
                     assert(tmp==this->subjectsList.size());
                     xmlReadingLog+="  Added "+CustomFETString::number(tmp)+" subjects\n";
                     reducedXmlLog+="Added "+CustomFETString::number(tmp)+" subjects\n";
              }
              else if(elem2.tagName()=="Subject_Tags_List"){
                     QSet<QString> activityTagsRead;
              
                     QMessageBox::information(parent, tr("FET information"), tr("Your file contains subject tags list"
                       ", which is named in versions>=5.5.0 activity tags list"));
              
                     int tmp=0;
                     for(QDomNode node3=elem2.firstChild(); !node3.isNull(); node3=node3.nextSibling()){
                            QDomElement elem3=node3.toElement();
                            if(elem3.isNull()){
                                   xmlReadingLog+="   Null node here\n";
                                   continue;
                            }
                            xmlReadingLog+="   Found "+elem3.tagName()+" tag\n";
                            if(elem3.tagName()=="Subject_Tag"){
                                   ActivityTag* activityTag=new ActivityTag();
                                   for(QDomNode node4=elem3.firstChild(); !node4.isNull(); node4=node4.nextSibling()){
                                          QDomElement elem4=node4.toElement();
                                          if(elem4.isNull()){
                                                 xmlReadingLog+="    Null node here\n";
                                                 continue;
                                          }
                                          xmlReadingLog+="    Found "+elem4.tagName()+" tag\n";
                                          if(elem4.tagName()=="Name"){
                                                 activityTag->name=elem4.text();
                                                 xmlReadingLog+="    Read activity tag name: "+activityTag->name+"\n";
                                          }
                                   }
                                   bool tmp2=activityTagsRead.contains(activityTag->name);
                                   if(tmp2){
                                          QMessageBox::warning(parent, tr("FET warning"),
                                           tr("Duplicate activity tag %1 found - ignoring").arg(activityTag->name));
                                          xmlReadingLog+="   Activity tag not added - duplicate\n";
                                   }
                                   else{
                                          activityTagsRead.insert(activityTag->name);
                                          addActivityTagFast(activityTag);
                                          tmp++;
                                          xmlReadingLog+="   Activity tag inserted\n";
                                   }
                            }
                     }
                     assert(tmp==this->activityTagsList.size());
                     xmlReadingLog+="  Added "+CustomFETString::number(tmp)+" activity tags\n";
                     reducedXmlLog+="Added "+CustomFETString::number(tmp)+" activity tags\n";
              }
              else if(elem2.tagName()=="Activity_Tags_List"){
                     QSet<QString> activityTagsRead;
              
                     int tmp=0;
                     for(QDomNode node3=elem2.firstChild(); !node3.isNull(); node3=node3.nextSibling()){
                            QDomElement elem3=node3.toElement();
                            if(elem3.isNull()){
                                   xmlReadingLog+="   Null node here\n";
                                   continue;
                            }
                            xmlReadingLog+="   Found "+elem3.tagName()+" tag\n";
                            if(elem3.tagName()=="Activity_Tag"){
                                   ActivityTag* activityTag=new ActivityTag();
                                   for(QDomNode node4=elem3.firstChild(); !node4.isNull(); node4=node4.nextSibling()){
                                          QDomElement elem4=node4.toElement();
                                          if(elem4.isNull()){
                                                 xmlReadingLog+="    Null node here\n";
                                                 continue;
                                          }
                                          xmlReadingLog+="    Found "+elem4.tagName()+" tag\n";
                                          if(elem4.tagName()=="Name"){
                                                 activityTag->name=elem4.text();
                                                 xmlReadingLog+="    Read activity tag name: "+activityTag->name+"\n";
                                          }
                                   }
                                   bool tmp2=activityTagsRead.contains(activityTag->name);
                                   if(tmp2){
                                          QMessageBox::warning(parent, tr("FET warning"),
                                           tr("Duplicate activity tag %1 found - ignoring").arg(activityTag->name));
                                          xmlReadingLog+="   Activity tag not added - duplicate\n";
                                   }
                                   else{
                                          activityTagsRead.insert(activityTag->name);
                                          addActivityTagFast(activityTag);
                                          tmp++;
                                          xmlReadingLog+="   Activity tag inserted\n";
                                   }
                            }
                     }
                     assert(tmp==this->activityTagsList.size());
                     xmlReadingLog+="  Added "+CustomFETString::number(tmp)+" activity tags\n";
                     reducedXmlLog+="Added "+CustomFETString::number(tmp)+" activity tags\n";
              }
              else if(elem2.tagName()=="Students_List"){
                     QHash<QString, StudentsSet*> studentsHash;
              
                     int tsgr=0;
                     int tgr=0;
              
                     int ny=0;
                     for(QDomNode node3=elem2.firstChild(); !node3.isNull(); node3=node3.nextSibling()){
                            QDomElement elem3=node3.toElement();
                            if(elem3.isNull()){
                                   xmlReadingLog+="   Null node here\n";
                                   continue;
                            }
                            xmlReadingLog+="   Found "+elem3.tagName()+" tag\n";
                            if(elem3.tagName()=="Year"){
                                   StudentsYear* sty=new StudentsYear();
                                   int ng=0;
                                   
                                   QSet<QString> groupsInYear;

                                   bool tmp2=this->addYearFast(sty);
                                   assert(tmp2==true);
                                   ny++;

                                   for(QDomNode node4=elem3.firstChild(); !node4.isNull(); node4=node4.nextSibling()){
                                          QDomElement elem4=node4.toElement();
                                          if(elem4.isNull()){
                                                 xmlReadingLog+="    Null node here\n";
                                                 continue;
                                          }
                                          xmlReadingLog+="    Found "+elem4.tagName()+" tag\n";
                                          if(elem4.tagName()=="Name"){
                                                 if(!skipDuplicatedStudentsSets){
                                                        QString nn=elem4.text();
                                                        //StudentsSet* ss=this->searchStudentsSet(nn);
                                                        StudentsSet* ss=studentsHash.value(nn, NULL);
                                                        if(ss!=NULL){
                                                               QString str;
                                                               
                                                               if(ss->type==STUDENTS_YEAR)
                                                                      str=tr("Trying to add year %1, which is already added as another year - your file will be loaded but probably contains errors, please correct them after loading").arg(nn);
                                                               else if(ss->type==STUDENTS_GROUP)
                                                                      str=tr("Trying to add year %1, which is already added as another group - your file will be loaded but probably contains errors, please correct them after loading").arg(nn);
                                                               else if(ss->type==STUDENTS_SUBGROUP)
                                                                      str=tr("Trying to add year %1, which is already added as another subgroup - your file will be loaded but probably contains errors, please correct them after loading").arg(nn);
                                                        
                                                               int t=QMessageBox::warning(parent, tr("FET warning"), str,
                                                                tr("Skip rest"), tr("See next"), QString(),
                                                                1, 0 );
                                   
                                                               if(t==0)
                                                                      skipDuplicatedStudentsSets=true;
                                                        }
                                                 }                                         
                                          
                                                 sty->name=elem4.text();
                                                 if(!studentsHash.contains(sty->name))
                                                        studentsHash.insert(sty->name, sty);
                                                 xmlReadingLog+="    Read year name: "+sty->name+"\n";
                                          }
                                          else if(elem4.tagName()=="Number_of_Students"){
                                                 sty->numberOfStudents=elem4.text().toInt();
                                                 xmlReadingLog+="    Read year number of students: "+CustomFETString::number(sty->numberOfStudents)+"\n";
                                          }
                                          else if(elem4.tagName()=="Group"){
                                                 StudentsGroup* stg=new StudentsGroup();
                                                 int ns=0;

                                                 QSet<QString> subgroupsInGroup;
                                                 
                                                 /*bool tmp4=this->addGroupFast(sty, stg);
                                                 assert(tmp4==true);
                                                 ng++;*/

                                                 for(QDomNode node5=elem4.firstChild(); !node5.isNull(); node5=node5.nextSibling()){
                                                        QDomElement elem5=node5.toElement();
                                                        if(elem5.isNull()){
                                                               xmlReadingLog+="     Null node here\n";
                                                               continue;
                                                        }
                                                        xmlReadingLog+="     Found "+elem5.tagName()+" tag\n";
                                                        if(elem5.tagName()=="Name"){
                                                               if(!skipDuplicatedStudentsSets){
                                                                      QString nn=elem5.text();
                                                                      StudentsSet* ss=studentsHash.value(nn, NULL);
                                                                      if(ss!=NULL){
                                                                             QString str;
                                                               
                                                                             if(ss->type==STUDENTS_YEAR)
                                                                                    str=tr("Trying to add group %1, which is already added as another year - your file will be loaded but probably contains errors, please correct them after loading").arg(nn);
                                                                             else if(ss->type==STUDENTS_GROUP){
                                                                                    if(groupsInYear.contains(nn)){
                                                                                           str=tr("Trying to add group %1 in year %2 but it is already added - your file will be loaded but probably contains errors, please correct them after loading").arg(nn).arg(sty->name);
                                                                                    }
                                                                                    else
                                                                                           str="";
                                                                             }
                                                                             else if(ss->type==STUDENTS_SUBGROUP)
                                                                                    str=tr("Trying to add group %1, which is already added as another subgroup - your file will be loaded but probably contains errors, please correct them after loading").arg(nn);
                                                        
                                                                             int t=1;
                                                                             if(str!=""){
                                                                                    t=QMessageBox::warning(parent, tr("FET warning"), str,
                                                                                     tr("Skip rest"), tr("See next"), QString(),
                                                                                     1, 0 );
                                                                             }
                                   
                                                                             if(t==0)
                                                                                    skipDuplicatedStudentsSets=true;
                                                                      }
                                                               }
                                                               
                                                               groupsInYear.insert(elem5.text());

                                                               if(studentsHash.contains(elem5.text())){
                                                                      delete stg;
                                                                      stg=(StudentsGroup*)(studentsHash.value(elem5.text()));

                                                                      bool tmp4=this->addGroupFast(sty, stg);
                                                                      assert(tmp4==true);
                                                                      //ng++;
                                                                      break;
                                                               }

                                                               bool tmp4=this->addGroupFast(sty, stg);
                                                               assert(tmp4==true);
                                                               ng++;

                                                               stg->name=elem5.text();
                                                               if(!studentsHash.contains(stg->name))
                                                                      studentsHash.insert(stg->name, stg);
                                                               xmlReadingLog+="     Read group name: "+stg->name+"\n";
                                                        }
                                                        else if(elem5.tagName()=="Number_of_Students"){
                                                               stg->numberOfStudents=elem5.text().toInt();
                                                               xmlReadingLog+="     Read group number of students: "+CustomFETString::number(stg->numberOfStudents)+"\n";
                                                        }
                                                        else if(elem5.tagName()=="Subgroup"){
                                                               StudentsSubgroup* sts=new StudentsSubgroup();

                                                               /*bool tmp6=this->addSubgroupFast(sty, stg, sts);
                                                               assert(tmp6==true);
                                                               ns++;*/

                                                               for(QDomNode node6=elem5.firstChild(); !node6.isNull(); node6=node6.nextSibling()){
                                                                      QDomElement elem6=node6.toElement();
                                                                      if(elem6.isNull()){
                                                                             xmlReadingLog+="     Null node here\n";
                                                                             continue;
                                                                      }
                                                                      xmlReadingLog+="     Found "+elem6.tagName()+" tag\n";
                                                                      if(elem6.tagName()=="Name"){
                                                                             if(!skipDuplicatedStudentsSets){
                                                                                    QString nn=elem6.text();
                                                                                    StudentsSet* ss=studentsHash.value(nn, NULL);
                                                                                    if(ss!=NULL){
                                                                                           QString str;
                                                               
                                                                                           if(ss->type==STUDENTS_YEAR)
                                                                                                  str=tr("Trying to add subgroup %1, which is already added as another year - your file will be loaded but probably contains errors, please correct them after loading").arg(nn);
                                                                                           else if(ss->type==STUDENTS_GROUP)
                                                                                                  str=tr("Trying to add subgroup %1, which is already added as another group - your file will be loaded but probably contains errors, please correct them after loading").arg(nn);
                                                                                           else if(ss->type==STUDENTS_SUBGROUP){
                                                                                                  if(subgroupsInGroup.contains(nn)){
                                                                                                         str=tr("Trying to add subgroup %1 in year %2, group %3 but it is already added - your file will be loaded but probably contains errors, please correct them after loading").arg(nn).arg(sty->name).arg(stg->name);
                                                                                                  }
                                                                                                  else
                                                                                                         str="";
                                                                                           }
                                                        
                                                                                           int t=1;
                                                                                           if(str!=""){
                                                                                                  t=QMessageBox::warning(parent, tr("FET warning"), str,
                                                                                                   tr("Skip rest"), tr("See next"), QString(),
                                                                                                   1, 0 );
                                                                                           }
                                                 
                                                                                           if(t==0)
                                                                                                  skipDuplicatedStudentsSets=true;
                                                                                    }
                                                                             }
                                                                             
                                                                             subgroupsInGroup.insert(elem6.text());

                                                                             if(studentsHash.contains(elem6.text())){
                                                                                    delete sts;
                                                                                    sts=(StudentsSubgroup*)(studentsHash.value(elem6.text()));

                                                                                    bool tmp6=this->addSubgroupFast(sty, stg, sts);
                                                                                    assert(tmp6==true);
                                                                                    //ns++;
                                                                                    break;
                                                                             }

                                                                             bool tmp6=this->addSubgroupFast(sty, stg, sts);
                                                                             assert(tmp6==true);
                                                                             ns++;
                                                                             
                                                                             sts->name=elem6.text();
                                                                             if(!studentsHash.contains(sts->name))
                                                                                    studentsHash.insert(sts->name, sts);
                                                                             xmlReadingLog+="     Read subgroup name: "+sts->name+"\n";
                                                                      }
                                                                      else if(elem6.tagName()=="Number_of_Students"){
                                                                             sts->numberOfStudents=elem6.text().toInt();
                                                                             xmlReadingLog+="     Read subgroup number of students: "+CustomFETString::number(sts->numberOfStudents)+"\n";
                                                                      }
                                                               }
                                                        }
                                                 }
                                                 if(ns == stg->subgroupsList.size()){
                                                        xmlReadingLog+="    Added "+CustomFETString::number(ns)+" subgroups\n";
                                                        tsgr+=ns;
                                                 //reducedXmlLog+="          Added "+CustomFETString::number(ns)+" subgroups\n";
                                                 }
                                          }
                                   }
                                   if(ng == sty->groupsList.size()){
                                          xmlReadingLog+="   Added "+CustomFETString::number(ng)+" groups\n";
                                          tgr+=ng;
                                          //reducedXmlLog+="   Added "+CustomFETString::number(ng)+" groups\n";
                                   }
                            }
                     }
                     xmlReadingLog+="  Added "+CustomFETString::number(ny)+" years\n";
                     reducedXmlLog+="Added "+CustomFETString::number(ny)+" students years\n";
                     //reducedXmlLog+="Added "+CustomFETString::number(tgr)+" students groups (see note below)\n";
                     reducedXmlLog+="Added "+CustomFETString::number(tgr)+" students groups\n";
                     //reducedXmlLog+="Added "+CustomFETString::number(tsgr)+" students subgroups (see note below)\n";
                     reducedXmlLog+="Added "+CustomFETString::number(tsgr)+" students subgroups\n";
                     assert(this->yearsList.size()==ny);

                     //BEGIN test for number of students is the same in all sets with the same name
                     bool reportWrongNumberOfStudents=true;
                     foreach(StudentsYear* year, yearsList){
                            assert(studentsHash.contains(year->name));
                            StudentsSet* sy=studentsHash.value(year->name);
                            if(sy->numberOfStudents!=year->numberOfStudents){
                                   if(reportWrongNumberOfStudents){
                                          QString str=tr("Minor problem found and corrected: year %1 has different number of students in two places (%2 and %3)", "%2 and %3 are number of students")
                                                 .arg(year->name).arg(sy->numberOfStudents).arg(year->numberOfStudents)
                                                 +
                                                 "\n\n"+
                                                 tr("Explanation: this is a minor problem, which appears if using overlapping students set, due to a bug in FET previous to version %1."
                                                 " FET will now correct this problem by setting the number of students for this year, in all places where it appears,"
                                                 " to the number that was found in the first appearance (%2). It is advisable to check the number of students for this year.")
                                                 .arg("5.12.1").arg(sy->numberOfStudents);
                                          int t=QMessageBox::warning(parent, tr("FET warning"), str,
                                                  tr("Skip rest"), tr("See next"), QString(),
                                                  1, 0 );
       
                                          if(t==0)
                                                 reportWrongNumberOfStudents=false;
                                   }
                                   year->numberOfStudents=sy->numberOfStudents;
                            }
                            
                            foreach(StudentsGroup* group, year->groupsList){
                                   assert(studentsHash.contains(group->name));
                                   StudentsSet* sg=studentsHash.value(group->name);
                                   if(sg->numberOfStudents!=group->numberOfStudents){
                                          if(reportWrongNumberOfStudents){
                                                 QString str=tr("Minor problem found and corrected: group %1 has different number of students in two places (%2 and %3)", "%2 and %3 are number of students")
                                                        .arg(group->name).arg(sg->numberOfStudents).arg(group->numberOfStudents)
                                                        +
                                                        "\n\n"+
                                                        tr("Explanation: this is a minor problem, which appears if using overlapping students set, due to a bug in FET previous to version %1."
                                                        " FET will now correct this problem by setting the number of students for this group, in all places where it appears,"
                                                        " to the number that was found in the first appearance (%2). It is advisable to check the number of students for this group.")
                                                        .arg("5.12.1").arg(sg->numberOfStudents);
                                                 int t=QMessageBox::warning(parent, tr("FET warning"), str,
                                                         tr("Skip rest"), tr("See next"), QString(),
                                                         1, 0 );
              
                                                 if(t==0)
                                                        reportWrongNumberOfStudents=false;
                                          }
                                          group->numberOfStudents=sg->numberOfStudents;
                                   }

                                   foreach(StudentsSubgroup* subgroup, group->subgroupsList){
                                          assert(studentsHash.contains(subgroup->name));
                                          StudentsSet* ss=studentsHash.value(subgroup->name);
                                          if(ss->numberOfStudents!=subgroup->numberOfStudents){
                                                 if(reportWrongNumberOfStudents){
                                                        QString str=tr("Minor problem found and corrected: subgroup %1 has different number of students in two places (%2 and %3)", "%2 and %3 are number of students")
                                                               .arg(subgroup->name).arg(ss->numberOfStudents).arg(subgroup->numberOfStudents)
                                                               +
                                                               "\n\n"+
                                                               tr("Explanation: this is a minor problem, which appears if using overlapping students set, due to a bug in FET previous to version %1."
                                                               " FET will now correct this problem by setting the number of students for this subgroup, in all places where it appears,"
                                                               " to the number that was found in the first appearance (%2). It is advisable to check the number of students for this subgroup.")
                                                               .arg("5.12.1").arg(ss->numberOfStudents);
                                                        int t=QMessageBox::warning(parent, tr("FET warning"), str,
                                                                tr("Skip rest"), tr("See next"), QString(),
                                                                1, 0 );
                     
                                                        if(t==0)
                                                               reportWrongNumberOfStudents=false;
                                                 }
                                                 subgroup->numberOfStudents=ss->numberOfStudents;
                                          }
                                   }
                            }
                     }
                     //END test for number of students is the same in all sets with the same name
              }
              else if(elem2.tagName()=="Activities_List"){
                     QSet<QString> allTeachers;
                     QHash<QString, int> studentsSetsCount;
                     QSet<QString> allSubjects;
                     QSet<QString> allActivityTags;
                     
                     foreach(Teacher* tch, this->teachersList)
                            allTeachers.insert(tch->name);

                     foreach(Subject* sbj, this->subjectsList)
                            allSubjects.insert(sbj->name);

                     foreach(ActivityTag* at, this->activityTagsList)
                            allActivityTags.insert(at->name);

                     foreach(StudentsYear* year, this->yearsList){
                            if(!studentsSetsCount.contains(year->name))
                                   studentsSetsCount.insert(year->name, year->numberOfStudents);
                            else if(studentsSetsCount.value(year->name)!=year->numberOfStudents){
                                   //cout<<"Mistake: year "<<qPrintable(year->name)<<" appears in more places with different number of students"<<endl;
                            }

                            foreach(StudentsGroup* group, year->groupsList){
                                   if(!studentsSetsCount.contains(group->name))
                                          studentsSetsCount.insert(group->name, group->numberOfStudents);
                                   else if(studentsSetsCount.value(group->name)!=group->numberOfStudents){
                                          //cout<<"Mistake: group "<<qPrintable(group->name)<<" appears in more places with different number of students"<<endl;
                                   }
                     
                                   foreach(StudentsSubgroup* subgroup, group->subgroupsList){
                                          if(!studentsSetsCount.contains(subgroup->name))
                                                 studentsSetsCount.insert(subgroup->name, subgroup->numberOfStudents);
                                          else if(studentsSetsCount.value(subgroup->name)!=subgroup->numberOfStudents){
                                                 //cout<<"Mistake: subgroup "<<qPrintable(subgroup->name)<<" appears in more places with different number of students"<<endl;
                                          }
                                   }
                            }
                     }

                     //int nchildrennodes=elem2.childNodes().length();
                     
                     /*QProgressDialog progress(parent);
                     progress.setLabelText(tr("Loading activities ... please wait"));
                     progress.setRange(0, nchildrennodes);
                     progress.setModal(true);*/
                     //progress.setCancelButton(parent);
                     
                     //int ttt=0;
              
                     int na=0;
                     for(QDomNode node3=elem2.firstChild(); !node3.isNull(); node3=node3.nextSibling()){
                     
                            /*progress.setValue(ttt);
                            pqapplication->processEvents();
                            if(progress.wasCanceled()){
                                   QMessageBox::information(parent, tr("FET information"), tr("Interrupted - only partial file was loaded"));
                                   return true;
                            }
                            
                            ttt++;*/
                     
                            QDomElement elem3=node3.toElement();
                            if(elem3.isNull()){
                                   xmlReadingLog+="   Null node here\n";
                                   continue;
                            }
                            xmlReadingLog+="   Found "+elem3.tagName()+" tag\n";
                            if(elem3.tagName()=="Activity"){
                                   bool correct=true;
                            
                                   QString cm=QString(""); //comments
                                   QString tn="";
                                   QStringList tl;
                                   QString sjn="";
                                   QString atn="";
                                   QStringList atl;
                                   QString stn="";
                                   QStringList stl;
                                   //int p=PARITY_NOT_INITIALIZED;
                                   int td=-1;
                                   int d=-1;
                                   int id=-1;
                                   int gid=-1;
                                   bool ac=true;
                                   int nos=-1;
                                   bool cnos=true;
                                   for(QDomNode node4=elem3.firstChild(); !node4.isNull(); node4=node4.nextSibling()){
                                          QDomElement elem4=node4.toElement();
                                          if(elem4.isNull()){
                                                 xmlReadingLog+="   Null node here\n";
                                                 continue;
                                          }
                                          xmlReadingLog+="    Found "+elem4.tagName()+" tag\n";
                                          if(elem4.tagName()=="Weekly"){
                                                 xmlReadingLog+="    Current activity is weekly - ignoring tag\n";
                                                 //assert(p==PARITY_NOT_INITIALIZED);
                                                 //p=PARITY_WEEKLY;
                                          }
                                          //old tag
                                          else if(elem4.tagName()=="Biweekly"){
                                                 xmlReadingLog+="    Current activity is fortnightly - ignoring tag\n";
                                                 //assert(p==PARITY_NOT_INITIALIZED);
                                                 //p=PARITY_FORTNIGHTLY;
                                          }
                                          else if(elem4.tagName()=="Fortnightly"){
                                                 xmlReadingLog+="    Current activity is fortnightly - ignoring tag\n";
                                                 //assert(p==PARITY_NOT_INITIALIZED);
                                                 //p=PARITY_FORTNIGHTLY;
                                          }
                                          else if(elem4.tagName()=="Active"){
                                                 if(elem4.text()=="yes" || elem4.text()=="true" || elem4.text()=="1"){
                                                        ac=true;
                                                        xmlReadingLog+="     Current activity is active\n";
                                                 }
                                                 else{
                                                        if(!(elem4.text()=="no" || elem4.text()=="false" || elem4.text()=="0")){
                                                               QMessageBox::warning(parent, tr("FET warning"),
                                                                tr("Found activity active tag which is not 'true', 'false', 'yes', 'no', '1' or '0'."
                                                                " The activity will be considered not active",
                                                                "Instructions for translators: please leave the 'true', 'false', 'yes' and 'no' fields untranslated, as they are in English"));
                                                        }
                                                        //assert(elem4.text()=="no" || elem4.text()=="false" || elem4.text()=="0");
                                                        ac=false;
                                                        xmlReadingLog+="     Current activity is not active\n";
                                                 }
                                          }
                                          else if(elem4.tagName()=="Comments"){
                                                 cm=elem4.text();
                                                 xmlReadingLog+="    Crt. activity comments="+cm+"\n";
                                          }
                                          else if(elem4.tagName()=="Teacher"){
                                                 tn=elem4.text();
                                                 xmlReadingLog+="    Crt. activity teacher="+tn+"\n";
                                                 tl.append(tn);
                                                 if(!allTeachers.contains(tn))
                                                 //if(this->searchTeacher(tn)<0)
                                                        correct=false;
                                          }
                                          else if(elem4.tagName()=="Subject"){
                                                 sjn=elem4.text();
                                                 xmlReadingLog+="    Crt. activity subject="+sjn+"\n";
                                                 if(!allSubjects.contains(sjn))
                                                 //if(this->searchSubject(sjn)<0)
                                                        correct=false;
                                          }
                                          else if(elem4.tagName()=="Subject_Tag"){
                                                 atn=elem4.text();
                                                 xmlReadingLog+="    Crt. activity activity_tag="+atn+"\n";
                                                 if(atn!="")
                                                        atl.append(atn);
                                                 if(atn!="" && !allActivityTags.contains(atn))
                                                 //if(atn!="" && this->searchActivityTag(atn)<0)
                                                        correct=false;
                                          }
                                          else if(elem4.tagName()=="Activity_Tag"){
                                                 atn=elem4.text();
                                                 xmlReadingLog+="    Crt. activity activity_tag="+atn+"\n";
                                                 if(atn!="")
                                                        atl.append(atn);
                                                 if(atn!="" && !allActivityTags.contains(atn))
                                                 //if(atn!="" && this->searchActivityTag(atn)<0)
                                                        correct=false;
                                          }
                                          else if(elem4.tagName()=="Students"){
                                                 stn=elem4.text();
                                                 xmlReadingLog+="    Crt. activity students+="+stn+"\n";
                                                 stl.append(stn);
                                                 if(!studentsSetsCount.contains(stn))
                                                 //if(this->searchStudentsSet(stn)==NULL)
                                                        correct=false;
                                          }
                                          else if(elem4.tagName()=="Duration"){
                                                 d=elem4.text().toInt();
                                                 xmlReadingLog+="    Crt. activity duration="+CustomFETString::number(d)+"\n";
                                          }
                                          else if(elem4.tagName()=="Total_Duration"){
                                                 td=elem4.text().toInt();
                                                 xmlReadingLog+="    Crt. activity total duration="+CustomFETString::number(td)+"\n";
                                          }
                                          else if(elem4.tagName()=="Id"){
                                                 id=elem4.text().toInt();
                                                 xmlReadingLog+="    Crt. activity id="+CustomFETString::number(id)+"\n";
                                          }
                                          else if(elem4.tagName()=="Activity_Group_Id"){
                                                 gid=elem4.text().toInt();
                                                 xmlReadingLog+="    Crt. activity group id="+CustomFETString::number(gid)+"\n";
                                          }
                                          else if(elem4.tagName()=="Number_Of_Students"){
                                                 cnos=false;
                                                 nos=elem4.text().toInt();
                                                 xmlReadingLog+="    Crt. activity number of students="+CustomFETString::number(nos)+"\n";
                                          }
                                   }
                                   if(correct){
                                          assert(id>=0 && gid>=0);
                                          assert(d>0);
                                          if(td<0)
                                                 td=d;
                                          
                                          if(cnos==true){
                                                 assert(nos==-1);
                                                 int _ns=0;
                                                 foreach(QString _s, stl){
                                                        assert(studentsSetsCount.contains(_s));
                                                        _ns+=studentsSetsCount.value(_s);
                                                 }
                                                 this->addSimpleActivityRulesFast(parent, id, gid, tl, sjn, atl, stl,
                                                        d, td, ac, cnos, nos, _ns);
                                          }
                                          else{
                                                 this->addSimpleActivity(parent, id, gid, tl, sjn, atl, stl,
                                                        d, td, ac, cnos, nos);
                                          }
                                          
                                          this->activitiesList[this->activitiesList.count()-1]->comments=cm;
                                          
                                          na++;
                                          xmlReadingLog+="   Added the activity\n";
                                   }
                                   else{
                                          xmlReadingLog+="   Activity with id ="+CustomFETString::number(id)+" contains invalid data - skipping\n";
                                          QMessageBox::warning(parent, tr("FET information"), 
                                           tr("Activity with id=%1 contains invalid data - skipping").arg(id));
                                   }
                            }
                     }
                     xmlReadingLog+="  Added "+CustomFETString::number(na)+" activities\n";
                     reducedXmlLog+="Added "+CustomFETString::number(na)+" activities\n";
              }
              else if(elem2.tagName()=="Equipments_List"){
                     QMessageBox::warning(parent, tr("FET warning"),
                      tr("File contains deprecated equipments list - will be ignored\n"));
              }
              else if(elem2.tagName()=="Buildings_List"){
                     QSet<QString> buildingsRead;
              
                     int tmp=0;
                     for(QDomNode node3=elem2.firstChild(); !node3.isNull(); node3=node3.nextSibling()){
                            QDomElement elem3=node3.toElement();
                            if(elem3.isNull()){
                                   xmlReadingLog+="   Null node here\n";
                                   continue;
                            }
                            xmlReadingLog+="   Found "+elem3.tagName()+" tag\n";
                            if(elem3.tagName()=="Building"){
                                   Building* bu=new Building();
                                   bu->name="";
                                   
                                   for(QDomNode node4=elem3.firstChild(); !node4.isNull(); node4=node4.nextSibling()){
                                          QDomElement elem4=node4.toElement();
                                          if(elem4.isNull()){
                                                 xmlReadingLog+="    Null node here\n";
                                                 continue;
                                          }
                                          xmlReadingLog+="    Found "+elem4.tagName()+" tag\n";
                                          if(elem4.tagName()=="Name"){
                                                 bu->name=elem4.text();
                                                 xmlReadingLog+="    Read building name: "+bu->name+"\n";
                                          }
                                   }

                                   bool tmp2=buildingsRead.contains(bu->name);
                                   if(tmp2){
                                          QMessageBox::warning(parent, tr("FET warning"),
                                           tr("Duplicate building %1 found - ignoring").arg(bu->name));
                                          xmlReadingLog+="   Building not added - duplicate\n";
                                   }
                                   else{
                                          buildingsRead.insert(bu->name);
                                          addBuildingFast(bu);
                                          tmp++;
                                          xmlReadingLog+="   Building inserted\n";
                                   }
                            }
                     }
                     assert(tmp==this->buildingsList.size());
                     xmlReadingLog+="  Added "+CustomFETString::number(tmp)+" buildings\n";
                     reducedXmlLog+="Added "+CustomFETString::number(tmp)+" buildings\n";
              }
              else if(elem2.tagName()=="Rooms_List"){
                     QSet<QString> roomsRead;
              
                     int tmp=0;
                     for(QDomNode node3=elem2.firstChild(); !node3.isNull(); node3=node3.nextSibling()){
                            QDomElement elem3=node3.toElement();
                            if(elem3.isNull()){
                                   xmlReadingLog+="   Null node here\n";
                                   continue;
                            }
                            xmlReadingLog+="   Found "+elem3.tagName()+" tag\n";
                            if(elem3.tagName()=="Room"){
                                   Room* rm=new Room();
                                   rm->name="";
                                   rm->capacity=MAX_ROOM_CAPACITY; //infinite, if not specified
                                   rm->building="";
                                   for(QDomNode node4=elem3.firstChild(); !node4.isNull(); node4=node4.nextSibling()){
                                          QDomElement elem4=node4.toElement();
                                          if(elem4.isNull()){
                                                 xmlReadingLog+="    Null node here\n";
                                                 continue;
                                          }
                                          xmlReadingLog+="    Found "+elem4.tagName()+" tag\n";
                                          if(elem4.tagName()=="Name"){
                                                 rm->name=elem4.text();
                                                 xmlReadingLog+="    Read room name: "+rm->name+"\n";
                                          }
                                          else if(elem4.tagName()=="Type"){
                                                 //rm->type=elem4.text();
                                                 xmlReadingLog+="    Ignoring old tag room type:\n";
                                          }
                                          else if(elem4.tagName()=="Capacity"){
                                                 rm->capacity=elem4.text().toInt();
                                                 xmlReadingLog+="    Read room capacity: "+CustomFETString::number(rm->capacity)+"\n";
                                          }
                                          else if(elem4.tagName()=="Equipment"){
                                                 //rm->addEquipment(elem4.text());
                                                 xmlReadingLog+="    Ignoring old tag - room equipment:\n";
                                          }
                                          else if(elem4.tagName()=="Building"){
                                                 rm->building=elem4.text();
                                                 xmlReadingLog+="    Read room building:\n"+rm->building;
                                          }
                                   }
                                   bool tmp2=roomsRead.contains(rm->name);
                                   if(tmp2){
                                          QMessageBox::warning(parent, tr("FET warning"),
                                           tr("Duplicate room %1 found - ignoring").arg(rm->name));
                                          xmlReadingLog+="   Room not added - duplicate\n";
                                   }
                                   else{
                                          roomsRead.insert(rm->name);
                                          addRoomFast(rm);
                                          tmp++;
                                          xmlReadingLog+="   Room inserted\n";
                                   }
                            }
                     }
                     assert(tmp==this->roomsList.size());
                     xmlReadingLog+="  Added "+CustomFETString::number(tmp)+" rooms\n";
                     reducedXmlLog+="Added "+CustomFETString::number(tmp)+" rooms\n";
              }
              else if(elem2.tagName()=="Time_Constraints_List"){
                     bool reportMaxBeginningsAtSecondHourChange=true;
                     bool reportMaxGapsChange=true;
                     bool reportStudentsSetNotAvailableChange=true;
                     bool reportTeacherNotAvailableChange=true;
                     bool reportBreakChange=true;
                     
                     bool reportActivityPreferredTimeChange=true;
                     
                     bool reportActivityPreferredTimesChange=true;
                     bool reportActivitiesPreferredTimesChange=true;
                     
                     bool reportUnspecifiedPermanentlyLockedTime=true;
                     
                     bool reportUnspecifiedDayOrHourPreferredStartingTime=true;
                     
#if 0
                     bool reportIncorrectMinDays=true;
#endif
              
                     int nc=0;
                     TimeConstraint *crt_constraint;
                     for(QDomNode node3=elem2.firstChild(); !node3.isNull(); node3=node3.nextSibling()){
                            crt_constraint=NULL;
                            QDomElement elem3=node3.toElement();
                            if(elem3.isNull()){
                                   xmlReadingLog+="   Null node here\n";
                                   continue;
                            }
                            xmlReadingLog+="   Found "+elem3.tagName()+" tag\n";
                            if(elem3.tagName()=="ConstraintBasicCompulsoryTime"){
                                   crt_constraint=readBasicCompulsoryTime(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintTeacherNotAvailable"){
                                   if(reportTeacherNotAvailableChange){
                                          int t=QMessageBox::information(parent, tr("FET information"),
                                           tr("File contains constraint teacher not available, which is old (it was improved in FET 5.5.0), and will be converted"
                                           " to the similar constraint of this type, constraint teacher not available times (a matrix)."),
                                            tr("Skip rest"), tr("See next"), QString(), 1, 0 );
                                          if(t==0)
                                                 reportTeacherNotAvailableChange=false;
                                   }

                                   crt_constraint=readTeacherNotAvailable(parent, elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintTeacherNotAvailableTimes"){
                                   crt_constraint=readTeacherNotAvailableTimes(parent, elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintTeacherMaxDaysPerWeek"){
                                   crt_constraint=readTeacherMaxDaysPerWeek(parent, elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintTeachersMaxDaysPerWeek"){
                                   crt_constraint=readTeachersMaxDaysPerWeek(parent, elem3, xmlReadingLog);
                            }

                            else if(elem3.tagName()=="ConstraintTeacherMinDaysPerWeek"){
                                   crt_constraint=readTeacherMinDaysPerWeek(parent, elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintTeachersMinDaysPerWeek"){
                                   crt_constraint=readTeachersMinDaysPerWeek(parent, elem3, xmlReadingLog);
                            }

                            else if(elem3.tagName()=="ConstraintTeacherIntervalMaxDaysPerWeek"){
                                   crt_constraint=readTeacherIntervalMaxDaysPerWeek(parent, elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintTeachersIntervalMaxDaysPerWeek"){
                                   crt_constraint=readTeachersIntervalMaxDaysPerWeek(parent, elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintStudentsSetIntervalMaxDaysPerWeek"){
                                   crt_constraint=readStudentsSetIntervalMaxDaysPerWeek(parent, elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintStudentsIntervalMaxDaysPerWeek"){
                                   crt_constraint=readStudentsIntervalMaxDaysPerWeek(parent, elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintStudentsSetNotAvailable"){
                                   if(reportStudentsSetNotAvailableChange){
                                          int t=QMessageBox::information(parent, tr("FET information"),
                                           tr("File contains constraint students set not available, which is old (it was improved in FET 5.5.0), and will be converted"
                                           " to the similar constraint of this type, constraint students set not available times (a matrix)."),
                                            tr("Skip rest"), tr("See next"), QString(), 1, 0 );
                                          if(t==0)
                                                 reportStudentsSetNotAvailableChange=false;
                                   }

                                   crt_constraint=readStudentsSetNotAvailable(parent, elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintStudentsSetNotAvailableTimes"){
                                   crt_constraint=readStudentsSetNotAvailableTimes(parent, elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintMinNDaysBetweenActivities"){
                                   crt_constraint=readMinNDaysBetweenActivities(parent, elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintMinDaysBetweenActivities"){
                                   crt_constraint=readMinDaysBetweenActivities(parent, elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintMaxDaysBetweenActivities"){
                                   crt_constraint=readMaxDaysBetweenActivities(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintMinGapsBetweenActivities"){
                                   crt_constraint=readMinGapsBetweenActivities(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintActivitiesNotOverlapping"){
                                   crt_constraint=readActivitiesNotOverlapping(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintActivitiesSameStartingTime"){
                                   crt_constraint=readActivitiesSameStartingTime(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintActivitiesSameStartingHour"){
                                   crt_constraint=readActivitiesSameStartingHour(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintActivitiesSameStartingDay"){
                                   crt_constraint=readActivitiesSameStartingDay(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintTeachersMaxHoursDaily"){
                                   crt_constraint=readTeachersMaxHoursDaily(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintTeacherMaxHoursDaily"){
                                   crt_constraint=readTeacherMaxHoursDaily(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintTeachersMaxHoursContinuously"){
                                   crt_constraint=readTeachersMaxHoursContinuously(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintTeacherMaxHoursContinuously"){
                                   crt_constraint=readTeacherMaxHoursContinuously(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintTeacherActivityTagMaxHoursContinuously"){
                                   crt_constraint=readTeacherActivityTagMaxHoursContinuously(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintTeachersActivityTagMaxHoursContinuously"){
                                   crt_constraint=readTeachersActivityTagMaxHoursContinuously(elem3, xmlReadingLog);
                            }

                            else if(elem3.tagName()=="ConstraintTeacherActivityTagMaxHoursDaily"){
                                   crt_constraint=readTeacherActivityTagMaxHoursDaily(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintTeachersActivityTagMaxHoursDaily"){
                                   crt_constraint=readTeachersActivityTagMaxHoursDaily(elem3, xmlReadingLog);
                            }

                            else if(elem3.tagName()=="ConstraintTeachersMinHoursDaily"){
                                   crt_constraint=readTeachersMinHoursDaily(parent, elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintTeacherMinHoursDaily"){
                                   crt_constraint=readTeacherMinHoursDaily(parent, elem3, xmlReadingLog);
                            }
                            else if((elem3.tagName()=="ConstraintTeachersSubgroupsMaxHoursDaily"
                             //TODO: erase the line below. It is only kept for compatibility with older versions
                             || elem3.tagName()=="ConstraintTeachersSubgroupsNoMoreThanXHoursDaily") && !skipDeprecatedConstraints){
                                   int t=QMessageBox::warning(parent, tr("FET warning"),
                                    tr("File contains deprecated constraint teachers subgroups max hours daily - will be ignored\n"),
                                    tr("Skip rest"), tr("See next"), QString(),
                                    1, 0 );
                                   
                                   if(t==0)
                                          skipDeprecatedConstraints=true;
                                   crt_constraint=NULL;
                            }
                            else if(elem3.tagName()=="ConstraintStudentsNHoursDaily" && !skipDeprecatedConstraints){
                                   int t=QMessageBox::warning(parent, tr("FET warning"),
                                    tr("File contains deprecated constraint students n hours daily - will be ignored\n"),
                                    tr("Skip rest"), tr("See next"), QString(),
                                    1, 0 );
                                   
                                   if(t==0)
                                          skipDeprecatedConstraints=true;
                                   crt_constraint=NULL;
                            }
                            else if(elem3.tagName()=="ConstraintStudentsSetNHoursDaily" && !skipDeprecatedConstraints){
                                   int t=QMessageBox::warning(parent, tr("FET warning"),
                                    tr("File contains deprecated constraint students set n hours daily - will be ignored\n"),
                                    tr("Skip rest"), tr("See next"), QString(),
                                    1, 0 );
                                   
                                   if(t==0)
                                          skipDeprecatedConstraints=true;
                                   crt_constraint=NULL;
                            }
                            else if(elem3.tagName()=="ConstraintStudentsMaxHoursDaily"){
                                   crt_constraint=readStudentsMaxHoursDaily(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintStudentsSetMaxHoursDaily"){
                                   crt_constraint=readStudentsSetMaxHoursDaily(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintStudentsMaxHoursContinuously"){
                                   crt_constraint=readStudentsMaxHoursContinuously(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintStudentsSetMaxHoursContinuously"){
                                   crt_constraint=readStudentsSetMaxHoursContinuously(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintStudentsSetActivityTagMaxHoursContinuously"){
                                   crt_constraint=readStudentsSetActivityTagMaxHoursContinuously(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintStudentsActivityTagMaxHoursContinuously"){
                                   crt_constraint=readStudentsActivityTagMaxHoursContinuously(elem3, xmlReadingLog);
                            }

                            else if(elem3.tagName()=="ConstraintStudentsSetActivityTagMaxHoursDaily"){
                                   crt_constraint=readStudentsSetActivityTagMaxHoursDaily(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintStudentsActivityTagMaxHoursDaily"){
                                   crt_constraint=readStudentsActivityTagMaxHoursDaily(elem3, xmlReadingLog);
                            }

                            else if(elem3.tagName()=="ConstraintStudentsMinHoursDaily"){
                                   crt_constraint=readStudentsMinHoursDaily(parent, elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintStudentsSetMinHoursDaily"){
                                   crt_constraint=readStudentsSetMinHoursDaily(parent, elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintActivityPreferredTime"){
                                   if(reportActivityPreferredTimeChange){
                                          int t=QMessageBox::information(parent, tr("FET information"),
                                           tr("File contains old constraint type activity preferred time, which will be converted"
                                           " to the newer similar constraint of this type, constraint activity preferred STARTING time."
                                           " This improvement is done in versions 5.5.9 and above"),
                                            tr("Skip rest"), tr("See next"), QString(), 1, 0 );
                                          if(t==0)
                                                 reportActivityPreferredTimeChange=false;
                                   }
                                   
                                   crt_constraint=readActivityPreferredTime(parent, elem3, xmlReadingLog,
                                          reportUnspecifiedPermanentlyLockedTime, reportUnspecifiedDayOrHourPreferredStartingTime);
                            }
                            
                            else if(elem3.tagName()=="ConstraintActivityPreferredStartingTime"){
                                   crt_constraint=readActivityPreferredStartingTime(parent, elem3, xmlReadingLog,
                                          reportUnspecifiedPermanentlyLockedTime, reportUnspecifiedDayOrHourPreferredStartingTime);
                            }
                            else if(elem3.tagName()=="ConstraintActivityEndsStudentsDay"){
                                   crt_constraint=readActivityEndsStudentsDay(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintActivitiesEndStudentsDay"){
                                   crt_constraint=readActivitiesEndStudentsDay(elem3, xmlReadingLog);
                            }
                            //old, with 2 and 3
                            else if(elem3.tagName()=="Constraint2ActivitiesConsecutive"){
                                   crt_constraint=read2ActivitiesConsecutive(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="Constraint2ActivitiesGrouped"){
                                   crt_constraint=read2ActivitiesGrouped(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="Constraint3ActivitiesGrouped"){
                                   crt_constraint=read3ActivitiesGrouped(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="Constraint2ActivitiesOrdered"){
                                   crt_constraint=read2ActivitiesOrdered(elem3, xmlReadingLog);
                            }
                            //end old
                            else if(elem3.tagName()=="ConstraintTwoActivitiesConsecutive"){
                                   crt_constraint=readTwoActivitiesConsecutive(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintTwoActivitiesGrouped"){
                                   crt_constraint=readTwoActivitiesGrouped(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintThreeActivitiesGrouped"){
                                   crt_constraint=readThreeActivitiesGrouped(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintTwoActivitiesOrdered"){
                                   crt_constraint=readTwoActivitiesOrdered(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintActivityEndsDay" && !skipDeprecatedConstraints ){
                                   int t=QMessageBox::warning(parent, tr("FET warning"),
                                    tr("File contains deprecated constraint activity ends day - will be ignored\n"),
                                    tr("Skip rest"), tr("See next"), QString(),
                                    1, 0 );
                                   
                                   if(t==0)
                                          skipDeprecatedConstraints=true;
                                   crt_constraint=NULL;
                            }
                            else if(elem3.tagName()=="ConstraintActivityPreferredTimes"){
                                   if(reportActivityPreferredTimesChange){
                                          int t=QMessageBox::information(parent, tr("FET information"),
                                           tr("Your file contains old constraint activity preferred times, which will be converted to"
                                           " new equivalent constraint activity preferred starting times. Beginning with FET-5.5.9 it is possible"
                                           " to specify: 1. the starting times of an activity (constraint activity preferred starting times)"
                                           " or: 2. the accepted time slots (constraint activity preferred time slots)."
                                           " If what you need is type 2 of this constraint, you will have to add it by yourself from the interface."),
                                            tr("Skip rest"), tr("See next"), QString(), 1, 0 );
                                          if(t==0)
                                                 reportActivityPreferredTimesChange=false;
                                   }
                                   
                                   crt_constraint=readActivityPreferredTimes(parent, elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintActivityPreferredTimeSlots"){
                                   crt_constraint=readActivityPreferredTimeSlots(parent, elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintActivityPreferredStartingTimes"){
                                   crt_constraint=readActivityPreferredStartingTimes(parent, elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintBreak"){
                                   if(reportBreakChange){
                                          int t=QMessageBox::information(parent, tr("FET information"),
                                           tr("File contains constraint break, which is old (it was improved in FET 5.5.0), and will be converted"
                                           " to the similar constraint of this type, constraint break times (a matrix)."),
                                            tr("Skip rest"), tr("See next"), QString(), 1, 0 );
                                          if(t==0)
                                                 reportBreakChange=false;
                                   }
                                   
                                   crt_constraint=readBreak(parent, elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintBreakTimes"){
                                   crt_constraint=readBreakTimes(parent, elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintTeachersNoGaps"){
                                   crt_constraint=readTeachersNoGaps(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintTeachersMaxGapsPerWeek"){
                                   crt_constraint=readTeachersMaxGapsPerWeek(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintTeacherMaxGapsPerWeek"){
                                   crt_constraint=readTeacherMaxGapsPerWeek(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintTeachersMaxGapsPerDay"){
                                   crt_constraint=readTeachersMaxGapsPerDay(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintTeacherMaxGapsPerDay"){
                                   crt_constraint=readTeacherMaxGapsPerDay(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintStudentsNoGaps"){
                                   if(reportMaxGapsChange){
                                          int t=QMessageBox::information(parent, tr("FET information"),
                                           tr("File contains constraint students no gaps, which is old (it was improved in FET 5.5.0), and will be converted"
                                           " to the similar constraint of this type, constraint students max gaps per week,"
                                           " with max gaps=0. If you like, you can modify this constraint to allow"
                                           " more gaps per week (normally not accepted in schools)"),
                                            tr("Skip rest"), tr("See next"), QString(), 1, 0 );
                                          if(t==0)
                                                 reportMaxGapsChange=false;
                                   }
                                   
                                   crt_constraint=readStudentsNoGaps(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintStudentsSetNoGaps"){
                                   if(reportMaxGapsChange){
                                          int t=QMessageBox::information(parent, tr("FET information"),
                                           tr("File contains constraint students set no gaps, which is old (it was improved in FET 5.5.0), and will be converted"
                                           " to the similar constraint of this type, constraint students set max gaps per week,"
                                           " with max gaps=0. If you like, you can modify this constraint to allow"
                                           " more gaps per week (normally not accepted in schools)"),
                                            tr("Skip rest"), tr("See next"), QString(), 1, 0 );
                                          if(t==0)
                                                 reportMaxGapsChange=false;
                                   }
                                   
                                   crt_constraint=readStudentsSetNoGaps(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintStudentsMaxGapsPerWeek"){
                                   crt_constraint=readStudentsMaxGapsPerWeek(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintStudentsSetMaxGapsPerWeek"){
                                   crt_constraint=readStudentsSetMaxGapsPerWeek(elem3, xmlReadingLog);
                            }

                            else if(elem3.tagName()=="ConstraintStudentsMaxGapsPerDay"){
                                   crt_constraint=readStudentsMaxGapsPerDay(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintStudentsSetMaxGapsPerDay"){
                                   crt_constraint=readStudentsSetMaxGapsPerDay(elem3, xmlReadingLog);
                            }

                            else if(elem3.tagName()=="ConstraintStudentsEarly"){
                                   if(reportMaxBeginningsAtSecondHourChange){
                                          int t=QMessageBox::information(parent, tr("FET information"),
                                           tr("File contains constraint students early, which is old (it was improved in FET 5.5.0), and will be converted"
                                           " to the similar constraint of this type, constraint students early max beginnings at second hour,"
                                           " with max beginnings=0. If you like, you can modify this constraint to allow"
                                           " more beginnings at second available hour (above 0 - this will make the timetable easier)"),
                                            tr("Skip rest"), tr("See next"), QString(), 1, 0 );
                                          if(t==0)
                                                 reportMaxBeginningsAtSecondHourChange=false;
                                   }
                                   
                                   crt_constraint=readStudentsEarly(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintStudentsEarlyMaxBeginningsAtSecondHour"){
                                   crt_constraint=readStudentsEarlyMaxBeginningsAtSecondHour(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintStudentsSetEarly"){
                                   if(reportMaxBeginningsAtSecondHourChange){
                                          int t=QMessageBox::information(parent, tr("FET information"),
                                           tr("File contains constraint students set early, which is old (it was improved in FET 5.5.0), and will be converted"
                                           " to the similar constraint of this type, constraint students set early max beginnings at second hour,"
                                           " with max beginnings=0. If you like, you can modify this constraint to allow"
                                           " more beginnings at second available hour (above 0 - this will make the timetable easier)"),
                                            tr("Skip rest"), tr("See next"), QString(), 1, 0 );
                                          if(t==0)
                                                 reportMaxBeginningsAtSecondHourChange=false;
                                   }
                                   
                                   crt_constraint=readStudentsSetEarly(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintStudentsSetEarlyMaxBeginningsAtSecondHour"){
                                   crt_constraint=readStudentsSetEarlyMaxBeginningsAtSecondHour(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintActivitiesPreferredTimes"){
                                   if(reportActivitiesPreferredTimesChange){
                                          int t=QMessageBox::information(parent, tr("FET information"),
                                           tr("Your file contains old constraint activities preferred times, which will be converted to"
                                           " new equivalent constraint activities preferred starting times. Beginning with FET-5.5.9 it is possible"
                                           " to specify: 1. the starting times of several activities (constraint activities preferred starting times)"
                                           " or: 2. the accepted time slots (constraint activities preferred time slots)."
                                           " If what you need is type 2 of this constraint, you will have to add it by yourself from the interface."),
                                            tr("Skip rest"), tr("See next"), QString(), 1, 0 );
                                          if(t==0)
                                                 reportActivitiesPreferredTimesChange=false;
                                   }
                                   
                                   crt_constraint=readActivitiesPreferredTimes(parent, elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintActivitiesPreferredTimeSlots"){
                                   crt_constraint=readActivitiesPreferredTimeSlots(parent, elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintActivitiesPreferredStartingTimes"){
                                   crt_constraint=readActivitiesPreferredStartingTimes(parent, elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintSubactivitiesPreferredTimeSlots"){
                                   crt_constraint=readSubactivitiesPreferredTimeSlots(parent, elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintSubactivitiesPreferredStartingTimes"){
                                   crt_constraint=readSubactivitiesPreferredStartingTimes(parent, elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintActivitiesOccupyMaxTimeSlotsFromSelection"){
                                   crt_constraint=readActivitiesOccupyMaxTimeSlotsFromSelection(parent, elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintActivitiesMaxSimultaneousInSelectedTimeSlots"){
                                   crt_constraint=readActivitiesMaxSimultaneousInSelectedTimeSlots(parent, elem3, xmlReadingLog);
                            }

                            else if(elem3.tagName()=="ConstraintTeachersSubjectTagsMaxHoursContinuously" && !skipDeprecatedConstraints){
                                   int t=QMessageBox::warning(parent, tr("FET warning"),
                                    tr("File contains deprecated constraint teachers subject tags max hours continuously - will be ignored\n"),
                                    tr("Skip rest"), tr("See next"), QString(),
                                    1, 0 );
                                                                                            
                                   if(t==0)
                                          skipDeprecatedConstraints=true;
                                   crt_constraint=NULL;
                            }
                            else if(elem3.tagName()=="ConstraintTeachersSubjectTagMaxHoursContinuously" && !skipDeprecatedConstraints){
                                   int t=QMessageBox::warning(parent, tr("FET warning"),
                                    tr("File contains deprecated constraint teachers subject tag max hours continuously - will be ignored\n"),
                                    tr("Skip rest"), tr("See next"), QString(),
                                    1, 0 );
                                                                                            
                                   if(t==0)
                                          skipDeprecatedConstraints=true;
                                   crt_constraint=NULL;
                            }

//corruptConstraintTime:
                            //here we skip invalid constraint or add valid one
                            if(crt_constraint!=NULL){
                                   assert(crt_constraint!=NULL);
                                   bool tmp=this->addTimeConstraint(crt_constraint);
                                   if(!tmp){
                                          QMessageBox::warning(parent, tr("FET information"),
                                           tr("Constraint\n%1\nnot added - must be a duplicate").
                                           arg(crt_constraint->getDetailedDescription(*this)));
                                          delete crt_constraint;
                                   }
                                   else
                                          nc++;
                            }
                     }
                     xmlReadingLog+="  Added "+CustomFETString::number(nc)+" time constraints\n";
                     reducedXmlLog+="Added "+CustomFETString::number(nc)+" time constraints\n";
              }
              else if(elem2.tagName()=="Space_Constraints_List"){
                     bool reportRoomNotAvailableChange=true;

                     bool reportUnspecifiedPermanentlyLockedSpace=true;

                     int nc=0;
                     SpaceConstraint *crt_constraint;
                     
                     for(QDomNode node3=elem2.firstChild(); !node3.isNull(); node3=node3.nextSibling()){
                            crt_constraint=NULL;
                            QDomElement elem3=node3.toElement();
                            if(elem3.isNull()){
                                   xmlReadingLog+="   Null node here\n";
                                   continue;
                            }
                            xmlReadingLog+="   Found "+elem3.tagName()+" tag\n";
                            if(elem3.tagName()=="ConstraintBasicCompulsorySpace"){
                                   crt_constraint=readBasicCompulsorySpace(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintRoomNotAvailable"){
                                   if(reportRoomNotAvailableChange){
                                          int t=QMessageBox::information(parent, tr("FET information"),
                                           tr("File contains constraint room not available, which is old (it was improved in FET 5.5.0), and will be converted"
                                           " to the similar constraint of this type, constraint room not available times (a matrix)."),
                                            tr("Skip rest"), tr("See next"), QString(), 1, 0 );
                                          if(t==0)
                                                 reportRoomNotAvailableChange=false;
                                   }
                                   
                                   crt_constraint=readRoomNotAvailable(parent, elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintRoomNotAvailableTimes"){
                                   crt_constraint=readRoomNotAvailableTimes(parent, elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintRoomTypeNotAllowedSubjects" && !skipDeprecatedConstraints){
                            
                                   int t=QMessageBox::warning(parent, tr("FET warning"),
                                    tr("File contains deprecated constraint room type not allowed subjects - will be ignored\n"),
                                    tr("Skip rest"), tr("See next"), QString(),
                                    1, 0);
                                    
                                   if(t==0)
                                          skipDeprecatedConstraints=true;
                                   crt_constraint=NULL;
                            }
                            else if(elem3.tagName()=="ConstraintSubjectRequiresEquipments" && !skipDeprecatedConstraints){
                            
                                   int t=QMessageBox::warning(parent, tr("FET warning"),
                                    tr("File contains deprecated constraint subject requires equipments - will be ignored\n"),
                                    tr("Skip rest"), tr("See next"), QString(),
                                    1, 0);
                                    
                                   if(t==0)
                                          skipDeprecatedConstraints=true;
                            
                                   crt_constraint=NULL;
                            }
                            else if(elem3.tagName()=="ConstraintSubjectSubjectTagRequireEquipments" && !skipDeprecatedConstraints){
                            
                                   int t=QMessageBox::warning(parent, tr("FET warning"),
                                    tr("File contains deprecated constraint subject tag requires equipments - will be ignored\n"),
                                    tr("Skip rest"), tr("See next"), QString(),
                                    1, 0);
                                    
                                   if(t==0)
                                          skipDeprecatedConstraints=true;
                                   crt_constraint=NULL;
                            }
                            else if(elem3.tagName()=="ConstraintTeacherRequiresRoom" && !skipDeprecatedConstraints){
                            
                                   int t=QMessageBox::warning(parent, tr("FET warning"),
                                    tr("File contains deprecated constraint teacher requires room - will be ignored\n"),
                                    tr("Skip rest"), tr("See next"), QString(),
                                    1, 0);
                                    
                                   if(t==0)
                                          skipDeprecatedConstraints=true;
                                   crt_constraint=NULL;
                            }
                            else if(elem3.tagName()=="ConstraintTeacherSubjectRequireRoom" && !skipDeprecatedConstraints){
                            
                                   int t=QMessageBox::warning(parent, tr("FET warning"),
                                    tr("File contains deprecated constraint teacher subject require room - will be ignored\n"),
                                    tr("Skip rest"), tr("See next"), QString(),
                                    1, 0);
                                    
                                   if(t==0)
                                          skipDeprecatedConstraints=true;
                                   crt_constraint=NULL;
                            }
                            else if(elem3.tagName()=="ConstraintMinimizeNumberOfRoomsForStudents" && !skipDeprecatedConstraints){
                            
                                   int t=QMessageBox::warning(parent, tr("FET warning"),
                                    tr("File contains deprecated constraint minimize number of rooms for students - will be ignored\n"),
                                    tr("Skip rest"), tr("See next"), QString(),
                                    1, 0);
                                    
                                   if(t==0)
                                          skipDeprecatedConstraints=true;
                                   crt_constraint=NULL;
                            }
                            else if(elem3.tagName()=="ConstraintMinimizeNumberOfRoomsForTeachers" && !skipDeprecatedConstraints){
                            
                                   int t=QMessageBox::warning(parent, tr("FET warning"),
                                    tr("File contains deprecated constraint minimize number of rooms for teachers - will be ignored\n"),
                                    tr("Skip rest"), tr("See next"), QString(),
                                    1, 0);
                                    
                                   if(t==0)
                                          skipDeprecatedConstraints=true;
                                   crt_constraint=NULL;
                            }
                            else if(elem3.tagName()=="ConstraintActivityPreferredRoom"){
                                   crt_constraint=readActivityPreferredRoom(parent, elem3, xmlReadingLog, reportUnspecifiedPermanentlyLockedSpace);
                            }
                            else if(elem3.tagName()=="ConstraintActivityPreferredRooms"){
                                   crt_constraint=readActivityPreferredRooms(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintActivitiesSameRoom" && !skipDeprecatedConstraints){
                            
                                   int t=QMessageBox::warning(parent, tr("FET warning"),
                                    tr("File contains deprecated constraint activities same room - will be ignored\n"),
                                    tr("Skip rest"), tr("See next"), QString(),
                                    1, 0);
                                    
                                   if(t==0)
                                          skipDeprecatedConstraints=true;
                                   crt_constraint=NULL;
                            }
                            else if(elem3.tagName()=="ConstraintSubjectPreferredRoom"){
                                   crt_constraint=readSubjectPreferredRoom(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintSubjectPreferredRooms"){
                                   crt_constraint=readSubjectPreferredRooms(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintSubjectSubjectTagPreferredRoom"){
                                   crt_constraint=readSubjectSubjectTagPreferredRoom(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintSubjectSubjectTagPreferredRooms"){
                                   crt_constraint=readSubjectSubjectTagPreferredRooms(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintSubjectActivityTagPreferredRoom"){
                                   crt_constraint=readSubjectActivityTagPreferredRoom(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintSubjectActivityTagPreferredRooms"){
                                   crt_constraint=readSubjectActivityTagPreferredRooms(elem3, xmlReadingLog);
                            }
                            //added 6 apr 2009
                            else if(elem3.tagName()=="ConstraintActivityTagPreferredRoom"){
                                   crt_constraint=readActivityTagPreferredRoom(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintActivityTagPreferredRooms"){
                                   crt_constraint=readActivityTagPreferredRooms(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintStudentsSetHomeRoom"){
                                   crt_constraint=readStudentsSetHomeRoom(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintStudentsSetHomeRooms"){
                                   crt_constraint=readStudentsSetHomeRooms(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintTeacherHomeRoom"){
                                   crt_constraint=readTeacherHomeRoom(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintTeacherHomeRooms"){
                                   crt_constraint=readTeacherHomeRooms(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintMaxBuildingChangesPerDayForTeachers" && !skipDeprecatedConstraints){
                            
                                   int t=QMessageBox::warning(parent, tr("FET warning"),
                                    tr("File contains deprecated constraint max building changes per day for teachers - will be ignored\n"),
                                    tr("Skip rest"), tr("See next"), QString(),
                                    1, 0);
                                    
                                   if(t==0)
                                          skipDeprecatedConstraints=true;
                                   crt_constraint=NULL;
                            }
                            else if(elem3.tagName()=="ConstraintMaxBuildingChangesPerDayForStudents" && !skipDeprecatedConstraints){
                            
                                   int t=QMessageBox::warning(parent, tr("FET warning"),
                                    tr("File contains deprecated constraint max building changes per day for students - will be ignored\n"),
                                    tr("Skip rest"), tr("See next"), QString(),
                                    1, 0);
                                    
                                   if(t==0)
                                          skipDeprecatedConstraints=true;
                                   crt_constraint=NULL;
                            }
                            else if(elem3.tagName()=="ConstraintMaxRoomChangesPerDayForTeachers" && !skipDeprecatedConstraints){
                            
                                   int t=QMessageBox::warning(parent, tr("FET warning"),
                                    tr("File contains deprecated constraint max room changes per day for teachers - will be ignored\n"),
                                    tr("Skip rest"), tr("See next"), QString(),
                                    1, 0);
                                    
                                   if(t==0)
                                          skipDeprecatedConstraints=true;
                                   crt_constraint=NULL;
                            }
                            else if(elem3.tagName()=="ConstraintMaxRoomChangesPerDayForStudents" && !skipDeprecatedConstraints){
                            
                                   int t=QMessageBox::warning(parent, tr("FET warning"),
                                    tr("File contains deprecated constraint max room changes per day for students - will be ignored\n"),
                                    tr("Skip rest"), tr("See next"), QString(),
                                    1, 0);
                                    
                                   if(t==0)
                                          skipDeprecatedConstraints=true;

                                   crt_constraint=NULL;
                            }
                            else if(elem3.tagName()=="ConstraintTeacherMaxBuildingChangesPerDay"){
                                   crt_constraint=readTeacherMaxBuildingChangesPerDay(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintTeachersMaxBuildingChangesPerDay"){
                                   crt_constraint=readTeachersMaxBuildingChangesPerDay(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintTeacherMaxBuildingChangesPerWeek"){
                                   crt_constraint=readTeacherMaxBuildingChangesPerWeek(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintTeachersMaxBuildingChangesPerWeek"){
                                   crt_constraint=readTeachersMaxBuildingChangesPerWeek(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintTeacherMinGapsBetweenBuildingChanges"){
                                   crt_constraint=readTeacherMinGapsBetweenBuildingChanges(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintTeachersMinGapsBetweenBuildingChanges"){
                                   crt_constraint=readTeachersMinGapsBetweenBuildingChanges(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintStudentsSetMaxBuildingChangesPerDay"){
                                   crt_constraint=readStudentsSetMaxBuildingChangesPerDay(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintStudentsMaxBuildingChangesPerDay"){
                                   crt_constraint=readStudentsMaxBuildingChangesPerDay(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintStudentsSetMaxBuildingChangesPerWeek"){
                                   crt_constraint=readStudentsSetMaxBuildingChangesPerWeek(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintStudentsMaxBuildingChangesPerWeek"){
                                   crt_constraint=readStudentsMaxBuildingChangesPerWeek(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintStudentsSetMinGapsBetweenBuildingChanges"){
                                   crt_constraint=readStudentsSetMinGapsBetweenBuildingChanges(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintStudentsMinGapsBetweenBuildingChanges"){
                                   crt_constraint=readStudentsMinGapsBetweenBuildingChanges(elem3, xmlReadingLog);
                            }
                            else if(elem3.tagName()=="ConstraintActivitiesOccupyMaxDifferentRooms"){
                                   crt_constraint=readActivitiesOccupyMaxDifferentRooms(elem3, xmlReadingLog);
                            }

//corruptConstraintSpace:
                            //here we skip invalid constraint or add valid one
                            if(crt_constraint!=NULL){
                                   assert(crt_constraint!=NULL);
                                   
                                   bool tmp=this->addSpaceConstraint(crt_constraint);
                                   if(!tmp){
                                          QMessageBox::warning(parent, tr("FET information"),
                                           tr("Constraint\n%1\nnot added - must be a duplicate").
                                           arg(crt_constraint->getDetailedDescription(*this)));
                                          delete crt_constraint;
                                   }
                                   else
                                          nc++;
                            }
                     }
                     xmlReadingLog+="  Added "+CustomFETString::number(nc)+" space constraints\n";
                     reducedXmlLog+="Added "+CustomFETString::number(nc)+" space constraints\n";
              }
       }

       this->internalStructureComputed=false;
       
       /*reducedXmlLog+="\n";
       reducedXmlLog+="Note: if you have overlapping students sets (years or groups), a group or a subgroup may be counted more than once. "
              "A unique group name is counted once for each year it belongs to and a unique subgroup name is counted once for each year+group it belongs to.\n";*/

       if(canWriteLogFile){
              //logStream<<xmlReadingLog;
              logStream<<reducedXmlLog;
       }

       if(file2.error()>0){
              QMessageBox::critical(parent, tr("FET critical"),
               tr("Saving of logging gave error code %1, which means you cannot see the log of reading the file. Please check your disk free space")
               .arg(file2.error()));
       }

       if(canWriteLogFile)
              file2.close();


       return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

TimeConstraint * Rules::read2ActivitiesConsecutive ( const QDomElement &  elem3,
FakeString xmlReadingLog 
) [private]

Definition at line 10603 of file rules.cpp.

                                                                                                    {
       assert(elem3.tagName()=="Constraint2ActivitiesConsecutive");
       ConstraintTwoActivitiesConsecutive* cn=new ConstraintTwoActivitiesConsecutive();
       for(QDomNode node4=elem3.firstChild(); !node4.isNull(); node4=node4.nextSibling()){
              QDomElement elem4=node4.toElement();
              if(elem4.isNull()){
                     xmlReadingLog+="    Null node here\n";
                     continue;
              }
              xmlReadingLog+="    Found "+elem4.tagName()+" tag\n";
              if(elem4.tagName()=="Weight"){
                     //cn->weight=customFETStrToDouble(elem4.text());
                     xmlReadingLog+="    Ignoring old tag - weight - making weight percentage=100\n";
                     cn->weightPercentage=100;
              }
              else if(elem4.tagName()=="Weight_Percentage"){
                     cn->weightPercentage=customFETStrToDouble(elem4.text());
                     xmlReadingLog+="    Adding weight percentage="+CustomFETString::number(cn->weightPercentage)+"\n";
              }
              else if(elem4.tagName()=="Active"){
                     if(elem4.text()=="false"){
                            cn->active=false;
                     }
              }
              else if(elem4.tagName()=="Comments"){
                     cn->comments=elem4.text();
              }
              else if(elem4.tagName()=="Compulsory"){
                     if(elem4.text()=="yes"){
                            //cn->compulsory=true;
                            xmlReadingLog+="    Ignoring old tag - Current constraint is compulsory\n";
                            cn->weightPercentage=100;
                     }
                     else{
                            //cn->compulsory=false;
                            xmlReadingLog+="    Old tag - current constraint is not compulsory - making weightPercentage=0%\n";
                            cn->weightPercentage=0;
                     }
              }
              else if(elem4.tagName()=="First_Activity_Id"){
                     cn->firstActivityId=elem4.text().toInt();
                     xmlReadingLog+="    Read first activity id="+CustomFETString::number(cn->firstActivityId)+"\n";
              }
              else if(elem4.tagName()=="Second_Activity_Id"){
                     cn->secondActivityId=elem4.text().toInt();
                     xmlReadingLog+="    Read second activity id="+CustomFETString::number(cn->secondActivityId)+"\n";
              }
       }
       return cn;
}

Here is the call graph for this function:

TimeConstraint * Rules::read2ActivitiesGrouped ( const QDomElement &  elem3,
FakeString xmlReadingLog 
) [private]

Definition at line 10654 of file rules.cpp.

                                                                                                {
       assert(elem3.tagName()=="Constraint2ActivitiesGrouped");
       ConstraintTwoActivitiesGrouped* cn=new ConstraintTwoActivitiesGrouped();
       for(QDomNode node4=elem3.firstChild(); !node4.isNull(); node4=node4.nextSibling()){
              QDomElement elem4=node4.toElement();
              if(elem4.isNull()){
                     xmlReadingLog+="    Null node here\n";
                     continue;
              }
              xmlReadingLog+="    Found "+elem4.tagName()+" tag\n";
              if(elem4.tagName()=="Weight"){
                     //cn->weight=customFETStrToDouble(elem4.text());
                     xmlReadingLog+="    Ignoring old tag - weight - making weight percentage=100\n";
                     cn->weightPercentage=100;
              }
              else if(elem4.tagName()=="Weight_Percentage"){
                     cn->weightPercentage=customFETStrToDouble(elem4.text());
                     xmlReadingLog+="    Adding weight percentage="+CustomFETString::number(cn->weightPercentage)+"\n";
              }
              else if(elem4.tagName()=="Active"){
                     if(elem4.text()=="false"){
                            cn->active=false;
                     }
              }
              else if(elem4.tagName()=="Comments"){
                     cn->comments=elem4.text();
              }
              else if(elem4.tagName()=="Compulsory"){
                     if(elem4.text()=="yes"){
                            //cn->compulsory=true;
                            xmlReadingLog+="    Ignoring old tag - Current constraint is compulsory\n";
                            cn->weightPercentage=100;
                     }
                     else{
                            //cn->compulsory=false;
                            xmlReadingLog+="    Old tag - current constraint is not compulsory - making weightPercentage=0%\n";
                            cn->weightPercentage=0;
                     }
              }
              else if(elem4.tagName()=="First_Activity_Id"){
                     cn->firstActivityId=elem4.text().toInt();
                     xmlReadingLog+="    Read first activity id="+CustomFETString::number(cn->firstActivityId)+"\n";
              }
              else if(elem4.tagName()=="Second_Activity_Id"){
                     cn->secondActivityId=elem4.text().toInt();
                     xmlReadingLog+="    Read second activity id="+CustomFETString::number(cn->secondActivityId)+"\n";
              }
       }
       return cn;
}

Here is the call graph for this function:

TimeConstraint * Rules::read2ActivitiesOrdered ( const QDomElement &  elem3,
FakeString xmlReadingLog 
) [private]

Definition at line 10743 of file rules.cpp.

                                                                                                {
       assert(elem3.tagName()=="Constraint2ActivitiesOrdered");
       ConstraintTwoActivitiesOrdered* cn=new ConstraintTwoActivitiesOrdered();
       for(QDomNode node4=elem3.firstChild(); !node4.isNull(); node4=node4.nextSibling()){
              QDomElement elem4=node4.toElement();
              if(elem4.isNull()){
                     xmlReadingLog+="    Null node here\n";
                     continue;
              }
              xmlReadingLog+="    Found "+elem4.tagName()+" tag\n";
              if(elem4.tagName()=="Weight"){
                     //cn->weight=customFETStrToDouble(elem4.text());
                     xmlReadingLog+="    Ignoring old tag - weight - making weight percentage=100\n";
                     cn->weightPercentage=100;
              }
              else if(elem4.tagName()=="Weight_Percentage"){
                     cn->weightPercentage=customFETStrToDouble(elem4.text());
                     xmlReadingLog+="    Adding weight percentage="+CustomFETString::number(cn->weightPercentage)+"\n";
              }
              else if(elem4.tagName()=="Active"){
                     if(elem4.text()=="false"){
                            cn->active=false;
                     }
              }
              else if(elem4.tagName()=="Comments"){
                     cn->comments=elem4.text();
              }
              else if(elem4.tagName()=="Compulsory"){
                     if(elem4.text()=="yes"){
                            //cn->compulsory=true;
                            xmlReadingLog+="    Ignoring old tag - Current constraint is compulsory\n";
                            cn->weightPercentage=100;
                     }
                     else{
                            //cn->compulsory=false;
                            xmlReadingLog+="    Old tag - current constraint is not compulsory - making weightPercentage=0%\n";
                            cn->weightPercentage=0;
                     }
              }
              else if(elem4.tagName()=="First_Activity_Id"){
                     cn->firstActivityId=elem4.text().toInt();
                     xmlReadingLog+="    Read first activity id="+CustomFETString::number(cn->firstActivityId)+"\n";
              }
              else if(elem4.tagName()=="Second_Activity_Id"){
                     cn->secondActivityId=elem4.text().toInt();
                     xmlReadingLog+="    Read second activity id="+CustomFETString::number(cn->secondActivityId)+"\n";
              }
       }
       return cn;
}

Here is the call graph for this function:

TimeConstraint * Rules::read3ActivitiesGrouped ( const QDomElement &  elem3,
FakeString xmlReadingLog 
) [private]

Definition at line 10705 of file rules.cpp.

                                                                                                {
       assert(elem3.tagName()=="Constraint3ActivitiesGrouped");
       ConstraintThreeActivitiesGrouped* cn=new ConstraintThreeActivitiesGrouped();
       for(QDomNode node4=elem3.firstChild(); !node4.isNull(); node4=node4.nextSibling()){
              QDomElement elem4=node4.toElement();
              if(elem4.isNull()){
                     xmlReadingLog+="    Null node here\n";
                     continue;
              }
              xmlReadingLog+="    Found "+elem4.tagName()+" tag\n";
              if(elem4.tagName()=="Weight_Percentage"){
                     cn->weightPercentage=customFETStrToDouble(elem4.text());
                     xmlReadingLog+="    Adding weight percentage="+CustomFETString::number(cn->weightPercentage)+"\n";
              }
              else if(elem4.tagName()=="Active"){
                     if(elem4.text()=="false"){
                            cn->active=false;
                     }
              }
              else if(elem4.tagName()=="Comments"){
                     cn->comments=elem4.text();
              }
              else if(elem4.tagName()=="First_Activity_Id"){
                     cn->firstActivityId=elem4.text().toInt();
                     xmlReadingLog+="    Read first activity id="+CustomFETString::number(cn->firstActivityId)+"\n";
              }
              else if(elem4.tagName()=="Second_Activity_Id"){
                     cn->secondActivityId=elem4.text().toInt();
                     xmlReadingLog+="    Read second activity id="+CustomFETString::number(cn->secondActivityId)+"\n";
              }
              else if(elem4.tagName()=="Third_Activity_Id"){
                     cn->thirdActivityId=elem4.text().toInt();
                     xmlReadingLog+="    Read third activity id="+CustomFETString::number(cn->thirdActivityId)+"\n";
              }
       }
       return cn;
}

Here is the call graph for this function:

TimeConstraint * Rules::readActivitiesEndStudentsDay ( const QDomElement &  elem3,
FakeString xmlReadingLog 
) [private]

Definition at line 10551 of file rules.cpp.

                                                                                                      {
       assert(elem3.tagName()=="ConstraintActivitiesEndStudentsDay");
       ConstraintActivitiesEndStudentsDay* cn=new ConstraintActivitiesEndStudentsDay();
       cn->teacherName="";
       cn->studentsName="";
       cn->subjectName="";
       cn->activityTagName="";
       
       //i=0;
       for(QDomNode node4=elem3.firstChild(); !node4.isNull(); node4=node4.nextSibling()){
              QDomElement elem4=node4.toElement();
              if(elem4.isNull()){
                     xmlReadingLog+="    Null node here\n";
                     continue;
              }
              xmlReadingLog+="    Found "+elem4.tagName()+" tag\n";
              if(elem4.tagName()=="Weight_Percentage"){
                     cn->weightPercentage=customFETStrToDouble(elem4.text());
                     xmlReadingLog+="    Adding weight percentage="+CustomFETString::number(cn->weightPercentage)+"\n";
              }
              else if(elem4.tagName()=="Active"){
                     if(elem4.text()=="false"){
                            cn->active=false;
                     }
              }
              else if(elem4.tagName()=="Comments"){
                     cn->comments=elem4.text();
              }
              else if(elem4.tagName()=="Teacher_Name"){
                     cn->teacherName=elem4.text();
                     xmlReadingLog+="    Read teacher name="+cn->teacherName+"\n";
              }
              else if(elem4.tagName()=="Students_Name"){
                     cn->studentsName=elem4.text();
                     xmlReadingLog+="    Read students name="+cn->studentsName+"\n";
              }
              else if(elem4.tagName()=="Subject_Name"){
                     cn->subjectName=elem4.text();
                     xmlReadingLog+="    Read subject name="+cn->subjectName+"\n";
              }
              else if(elem4.tagName()=="Subject_Tag_Name"){
                     cn->activityTagName=elem4.text();
                     xmlReadingLog+="    Read activity tag name="+cn->activityTagName+"\n";
              }
              else if(elem4.tagName()=="Activity_Tag_Name"){
                     cn->activityTagName=elem4.text();
                     xmlReadingLog+="    Read activity tag name="+cn->activityTagName+"\n";
              }
       }
       return cn;
}

Here is the call graph for this function:

TimeConstraint * Rules::readActivitiesMaxSimultaneousInSelectedTimeSlots ( QWidget *  parent,
const QDomElement &  elem3,
FakeString xmlReadingLog 
) [private]

Definition at line 13115 of file rules.cpp.

                                                                                                                                           {
       assert(elem3.tagName()=="ConstraintActivitiesMaxSimultaneousInSelectedTimeSlots");
       ConstraintActivitiesMaxSimultaneousInSelectedTimeSlots* cn=new ConstraintActivitiesMaxSimultaneousInSelectedTimeSlots();
       
       int ac=0;
       int tsc=0;
       int i=0;
       
       for(QDomNode node4=elem3.firstChild(); !node4.isNull(); node4=node4.nextSibling()){
              QDomElement elem4=node4.toElement();
              if(elem4.isNull()){
                     xmlReadingLog+="    Null node here\n";
                     continue;
              }
              xmlReadingLog+="    Found "+elem4.tagName()+" tag\n";

              if(elem4.tagName()=="Weight_Percentage"){
                     cn->weightPercentage=customFETStrToDouble(elem4.text());
                     xmlReadingLog+="    Adding weight percentage="+CustomFETString::number(cn->weightPercentage)+"\n";
              }
              else if(elem4.tagName()=="Active"){
                     if(elem4.text()=="false"){
                            cn->active=false;
                     }
              }
              else if(elem4.tagName()=="Comments"){
                     cn->comments=elem4.text();
              }
              else if(elem4.tagName()=="Number_of_Activities"){
                     ac=elem4.text().toInt();
                     xmlReadingLog+="    Read number of activities="+CustomFETString::number(ac)+"\n";
              }
              else if(elem4.tagName()=="Activity_Id"){
                     cn->activitiesIds.append(elem4.text().toInt());
                     xmlReadingLog+="    Read activity id="+CustomFETString::number(cn->activitiesIds[cn->activitiesIds.count()-1])+"\n";
              }
              else if(elem4.tagName()=="Number_of_Selected_Time_Slots"){
                     tsc=elem4.text().toInt();
                     xmlReadingLog+="    Read number of selected time slots="+CustomFETString::number(tsc)+"\n";
              }
              else if(elem4.tagName()=="Selected_Time_Slot"){
                     xmlReadingLog+="    Read: selected time slot\n";

                     for(QDomNode node5=elem4.firstChild(); !node5.isNull(); node5=node5.nextSibling()){
                            QDomElement elem5=node5.toElement();
                            if(elem5.isNull()){
                                   xmlReadingLog+="    Null node here\n";
                                   continue;
                            }
                            xmlReadingLog+="    Found "+elem5.tagName()+" tag\n";
                            if(elem5.tagName()=="Selected_Day"){
                                   cn->selectedDays.append(0);
                                   assert(cn->selectedDays.count()-1==i);
                                   for(cn->selectedDays[i]=0; cn->selectedDays[i]<this->nDaysPerWeek; cn->selectedDays[i]++)
                                          if(this->daysOfTheWeek[cn->selectedDays[i]]==elem5.text())
                                                 break;
                                                 
                                   if(cn->selectedDays[i]>=this->nDaysPerWeek){
                                          QMessageBox::information(parent, tr("FET information"), 
                                                 tr("Constraint ActivitiesMaxSimultaneousInSelectedTimeSlots day corrupt, day %1 is inexistent ... ignoring constraint")
                                                 .arg(elem5.text()));
                                          delete cn;
                                          cn=NULL;
                                          //goto corruptConstraintTime;
                                          return NULL;
                                   }
                                                 
                                   assert(cn->selectedDays[i]<this->nDaysPerWeek);
                                   xmlReadingLog+="    Selected day="+this->daysOfTheWeek[cn->selectedDays[i]]+"("+CustomFETString::number(i)+")"+"\n";
                            }
                            else if(elem5.tagName()=="Selected_Hour"){
                                   cn->selectedHours.append(0);
                                   assert(cn->selectedHours.count()-1==i);
                                   for(cn->selectedHours[i]=0; cn->selectedHours[i] < this->nHoursPerDay; cn->selectedHours[i]++)
                                          if(this->hoursOfTheDay[cn->selectedHours[i]]==elem5.text())
                                                 break;
                                                 
                                   if(cn->selectedHours[i]>=this->nHoursPerDay){
                                          QMessageBox::information(parent, tr("FET information"), 
                                                 tr(" Constraint ActivitiesMaxSimultaneousInSelectedTimeSlots hour corrupt, hour %1 is inexistent ... ignoring constraint")
                                                 .arg(elem5.text()));
                                          delete cn;
                                          cn=NULL;
                                          //goto corruptConstraintTime;
                                          return NULL;
                                   }
                                                 
                                   assert(cn->selectedHours[i]>=0 && cn->selectedHours[i] < this->nHoursPerDay);
                                   xmlReadingLog+="    Selected hour="+this->hoursOfTheDay[cn->selectedHours[i]]+"\n";
                            }
                     }

                     i++;
              }
              else if(elem4.tagName()=="Max_Number_of_Simultaneous_Activities"){
                     cn->maxSimultaneous=elem4.text().toInt();
                     xmlReadingLog+="    Read max number of simultaneous activities="+CustomFETString::number(cn->maxSimultaneous)+"\n";
              }
       }
       
       assert(ac==cn->activitiesIds.count());
       
       assert(i==tsc);
       assert(i==cn->selectedDays.count());
       assert(i==cn->selectedHours.count());
       return cn;
}

Here is the call graph for this function:

TimeConstraint * Rules::readActivitiesNotOverlapping ( const QDomElement &  elem3,
FakeString xmlReadingLog 
) [private]

Definition at line 9001 of file rules.cpp.

                                                                                                      {
       assert(elem3.tagName()=="ConstraintActivitiesNotOverlapping");
       ConstraintActivitiesNotOverlapping* cn=new ConstraintActivitiesNotOverlapping();
       int n_act=0;
       cn->activitiesId.clear();
       for(QDomNode node4=elem3.firstChild(); !node4.isNull(); node4=node4.nextSibling()){
              QDomElement elem4=node4.toElement();
              if(elem4.isNull()){
                     xmlReadingLog+="    Null node here\n";
                     continue;
              }
              xmlReadingLog+="    Found "+elem4.tagName()+" tag\n";
              if(elem4.tagName()=="Weight"){
                     //cn->weight=customFETStrToDouble(elem4.text());
                     xmlReadingLog+="    Ignoring old tag - weight - making weight percentage=100\n";
                     cn->weightPercentage=100;
              }
              else if(elem4.tagName()=="Weight_Percentage"){
                     cn->weightPercentage=customFETStrToDouble(elem4.text());
                     xmlReadingLog+="    Adding weight percentage="+CustomFETString::number(cn->weightPercentage)+"\n";
              }
              else if(elem4.tagName()=="Active"){
                     if(elem4.text()=="false"){
                            cn->active=false;
                     }
              }
              else if(elem4.tagName()=="Comments"){
                     cn->comments=elem4.text();
              }
              else if(elem4.tagName()=="Compulsory"){
                     if(elem4.text()=="yes"){
                            //cn->compulsory=true;
                            xmlReadingLog+="    Ignoring old tag - Current constraint is compulsory\n";
                            cn->weightPercentage=100;
                     }
                     else{
                            //cn->compulsory=false;
                            xmlReadingLog+="    Old tag - current constraint is not compulsory - making weightPercentage=0%\n";
                            cn->weightPercentage=0;
                     }
              }
              else if(elem4.tagName()=="Number_of_Activities"){
                     cn->n_activities=elem4.text().toInt();
                     xmlReadingLog+="    Read n_activities="+CustomFETString::number(cn->n_activities)+"\n";
              }
              else if(elem4.tagName()=="Activity_Id"){
                     //cn->activitiesId[n_act]=elem4.text().toInt();
                     cn->activitiesId.append(elem4.text().toInt());
                     assert(n_act==cn->activitiesId.count()-1);
                     xmlReadingLog+="    Read activity id="+CustomFETString::number(cn->activitiesId[n_act])+"\n";
                     n_act++;
              }
       }
       assert(n_act==cn->n_activities);
       return cn;
}

Here is the call graph for this function:

SpaceConstraint * Rules::readActivitiesOccupyMaxDifferentRooms ( const QDomElement &  elem3,
FakeString xmlReadingLog 
) [private]

Definition at line 14642 of file rules.cpp.

                                                                                                                {
       assert(elem3.tagName()=="ConstraintActivitiesOccupyMaxDifferentRooms");
       ConstraintActivitiesOccupyMaxDifferentRooms* cn=new ConstraintActivitiesOccupyMaxDifferentRooms();
       
       int ac=0;
       
       for(QDomNode node4=elem3.firstChild(); !node4.isNull(); node4=node4.nextSibling()){
              QDomElement elem4=node4.toElement();
              if(elem4.isNull()){
                     xmlReadingLog+="    Null node here\n";
                     continue;
              }
              xmlReadingLog+="    Found "+elem4.tagName()+" tag\n";

              if(elem4.tagName()=="Weight_Percentage"){
                     cn->weightPercentage=customFETStrToDouble(elem4.text());
                     xmlReadingLog+="    Adding weight percentage="+CustomFETString::number(cn->weightPercentage)+"\n";
              }
              else if(elem4.tagName()=="Active"){
                     if(elem4.text()=="false"){
                            cn->active=false;
                     }
              }
              else if(elem4.tagName()=="Comments"){
                     cn->comments=elem4.text();
              }
              else if(elem4.tagName()=="Number_of_Activities"){
                     ac=elem4.text().toInt();
                     xmlReadingLog+="    Read number of activities="+CustomFETString::number(ac)+"\n";
              }
              else if(elem4.tagName()=="Activity_Id"){
                     cn->activitiesIds.append(elem4.text().toInt());
                     xmlReadingLog+="    Read activity id="+CustomFETString::number(cn->activitiesIds[cn->activitiesIds.count()-1])+"\n";
              }
              else if(elem4.tagName()=="Max_Number_of_Different_Rooms"){
                     cn->maxDifferentRooms=elem4.text().toInt();
                     xmlReadingLog+="    Read max number of different rooms="+CustomFETString::number(cn->maxDifferentRooms)+"\n";
              }
       }
       
       assert(ac==cn->activitiesIds.count());
       
       return cn;
}

Here is the call graph for this function:

TimeConstraint * Rules::readActivitiesOccupyMaxTimeSlotsFromSelection ( QWidget *  parent,
const QDomElement &  elem3,
FakeString xmlReadingLog 
) [private]

Definition at line 13005 of file rules.cpp.

                                                                                                                                        {
       assert(elem3.tagName()=="ConstraintActivitiesOccupyMaxTimeSlotsFromSelection");
       ConstraintActivitiesOccupyMaxTimeSlotsFromSelection* cn=new ConstraintActivitiesOccupyMaxTimeSlotsFromSelection();
       
       int ac=0;
       int tsc=0;
       int i=0;
       
       for(QDomNode node4=elem3.firstChild(); !node4.isNull(); node4=node4.nextSibling()){
              QDomElement elem4=node4.toElement();
              if(elem4.isNull()){
                     xmlReadingLog+="    Null node here\n";
                     continue;
              }
              xmlReadingLog+="    Found "+elem4.tagName()+" tag\n";

              if(elem4.tagName()=="Weight_Percentage"){
                     cn->weightPercentage=customFETStrToDouble(elem4.text());
                     xmlReadingLog+="    Adding weight percentage="+CustomFETString::number(cn->weightPercentage)+"\n";
              }
              else if(elem4.tagName()=="Active"){
                     if(elem4.text()=="false"){
                            cn->active=false;
                     }
              }
              else if(elem4.tagName()=="Comments"){
                     cn->comments=elem4.text();
              }
              else if(elem4.tagName()=="Number_of_Activities"){
                     ac=elem4.text().toInt();
                     xmlReadingLog+="    Read number of activities="+CustomFETString::number(ac)+"\n";
              }
              else if(elem4.tagName()=="Activity_Id"){
                     cn->activitiesIds.append(elem4.text().toInt());
                     xmlReadingLog+="    Read activity id="+CustomFETString::number(cn->activitiesIds[cn->activitiesIds.count()-1])+"\n";
              }
              else if(elem4.tagName()=="Number_of_Selected_Time_Slots"){
                     tsc=elem4.text().toInt();
                     xmlReadingLog+="    Read number of selected time slots="+CustomFETString::number(tsc)+"\n";
              }
              else if(elem4.tagName()=="Selected_Time_Slot"){
                     xmlReadingLog+="    Read: selected time slot\n";

                     for(QDomNode node5=elem4.firstChild(); !node5.isNull(); node5=node5.nextSibling()){
                            QDomElement elem5=node5.toElement();
                            if(elem5.isNull()){
                                   xmlReadingLog+="    Null node here\n";
                                   continue;
                            }
                            xmlReadingLog+="    Found "+elem5.tagName()+" tag\n";
                            if(elem5.tagName()=="Selected_Day"){
                                   cn->selectedDays.append(0);
                                   assert(cn->selectedDays.count()-1==i);
                                   for(cn->selectedDays[i]=0; cn->selectedDays[i]<this->nDaysPerWeek; cn->selectedDays[i]++)
                                          if(this->daysOfTheWeek[cn->selectedDays[i]]==elem5.text())
                                                 break;
                                                 
                                   if(cn->selectedDays[i]>=this->nDaysPerWeek){
                                          QMessageBox::information(parent, tr("FET information"), 
                                                 tr("Constraint ActivitiesOccupyMaxTimeSlotsFromSelection day corrupt, day %1 is inexistent ... ignoring constraint")
                                                 .arg(elem5.text()));
                                          delete cn;
                                          cn=NULL;
                                          //goto corruptConstraintTime;
                                          return NULL;
                                   }
                                                 
                                   assert(cn->selectedDays[i]<this->nDaysPerWeek);
                                   xmlReadingLog+="    Selected day="+this->daysOfTheWeek[cn->selectedDays[i]]+"("+CustomFETString::number(i)+")"+"\n";
                            }
                            else if(elem5.tagName()=="Selected_Hour"){
                                   cn->selectedHours.append(0);
                                   assert(cn->selectedHours.count()-1==i);
                                   for(cn->selectedHours[i]=0; cn->selectedHours[i] < this->nHoursPerDay; cn->selectedHours[i]++)
                                          if(this->hoursOfTheDay[cn->selectedHours[i]]==elem5.text())
                                                 break;
                                                 
                                   if(cn->selectedHours[i]>=this->nHoursPerDay){
                                          QMessageBox::information(parent, tr("FET information"), 
                                                 tr(" Constraint ActivitiesOccupyMaxTimeSlotsFromSelection hour corrupt, hour %1 is inexistent ... ignoring constraint")
                                                 .arg(elem5.text()));
                                          delete cn;
                                          cn=NULL;
                                          //goto corruptConstraintTime;
                                          return NULL;
                                   }
                                                 
                                   assert(cn->selectedHours[i]>=0 && cn->selectedHours[i] < this->nHoursPerDay);
                                   xmlReadingLog+="    Selected hour="+this->hoursOfTheDay[cn->selectedHours[i]]+"\n";
                            }
                     }

                     i++;
              }
              else if(elem4.tagName()=="Max_Number_of_Occupied_Time_Slots"){
                     cn->maxOccupiedTimeSlots=elem4.text().toInt();
                     xmlReadingLog+="    Read max number of occupied time slots="+CustomFETString::number(cn->maxOccupiedTimeSlots)+"\n";
              }
       }
       
       assert(ac==cn->activitiesIds.count());
       
       assert(i==tsc);
       assert(i==cn->selectedDays.count());
       assert(i==cn->selectedHours.count());
       return cn;
}

Here is the call graph for this function:

TimeConstraint * Rules::readActivitiesPreferredStartingTimes ( QWidget *  parent,
const QDomElement &  elem3,
FakeString xmlReadingLog 
) [private]

Definition at line 12570 of file rules.cpp.

                                                                                                                               {
       assert(elem3.tagName()=="ConstraintActivitiesPreferredStartingTimes");
       ConstraintActivitiesPreferredStartingTimes* cn=new ConstraintActivitiesPreferredStartingTimes();
       cn->nPreferredStartingTimes_L=0;
       int i;
       /*for(i=0; i<MAX_N_CONSTRAINT_ACTIVITIES_PREFERRED_STARTING_TIMES; i++){
              cn->days[i] = cn->hours[i] = -1;
       }*/
       cn->teacherName="";
       cn->studentsName="";
       cn->subjectName="";
       cn->activityTagName="";
       
       i=0;
       for(QDomNode node4=elem3.firstChild(); !node4.isNull(); node4=node4.nextSibling()){
              QDomElement elem4=node4.toElement();
              if(elem4.isNull()){
                     xmlReadingLog+="    Null node here\n";
                     continue;
              }
              xmlReadingLog+="    Found "+elem4.tagName()+" tag\n";
              if(elem4.tagName()=="Weight"){
                     //cn->weight=customFETStrToDouble(elem4.text());
                     xmlReadingLog+="    Ignoring old tag - weight - making weight percentage=100\n";
                     cn->weightPercentage=100;
              }
              else if(elem4.tagName()=="Weight_Percentage"){
                     cn->weightPercentage=customFETStrToDouble(elem4.text());
                     xmlReadingLog+="    Adding weight percentage="+CustomFETString::number(cn->weightPercentage)+"\n";
              }
              else if(elem4.tagName()=="Active"){
                     if(elem4.text()=="false"){
                            cn->active=false;
                     }
              }
              else if(elem4.tagName()=="Comments"){
                     cn->comments=elem4.text();
              }
              else if(elem4.tagName()=="Compulsory"){
                     if(elem4.text()=="yes"){
                            //cn->compulsory=true;
                            xmlReadingLog+="    Ignoring old tag - Current constraint is compulsory\n";
                            cn->weightPercentage=100;
                     }
                     else{
                            //cn->compulsory=false;
                            xmlReadingLog+="    Old tag - current constraint is not compulsory - making weightPercentage=0%\n";
                            cn->weightPercentage=0;
                     }
              }
              else if(elem4.tagName()=="Teacher_Name"){
                     cn->teacherName=elem4.text();
                     xmlReadingLog+="    Read teacher name="+cn->teacherName+"\n";
              }
              else if(elem4.tagName()=="Students_Name"){
                     cn->studentsName=elem4.text();
                     xmlReadingLog+="    Read students name="+cn->studentsName+"\n";
              }
              else if(elem4.tagName()=="Subject_Name"){
                     cn->subjectName=elem4.text();
                     xmlReadingLog+="    Read subject name="+cn->subjectName+"\n";
              }
              else if(elem4.tagName()=="Subject_Tag_Name"){
                     cn->activityTagName=elem4.text();
                     xmlReadingLog+="    Read activity tag name="+cn->activityTagName+"\n";
              }
              else if(elem4.tagName()=="Activity_Tag_Name"){
                     cn->activityTagName=elem4.text();
                     xmlReadingLog+="    Read activity tag name="+cn->activityTagName+"\n";
              }
              else if(elem4.tagName()=="Number_of_Preferred_Starting_Times"){
                     cn->nPreferredStartingTimes_L=elem4.text().toInt();
                     xmlReadingLog+="    Read number of preferred starting times="+CustomFETString::number(cn->nPreferredStartingTimes_L)+"\n";
              }
              else if(elem4.tagName()=="Preferred_Starting_Time"){
                     xmlReadingLog+="    Read: preferred starting time\n";

                     for(QDomNode node5=elem4.firstChild(); !node5.isNull(); node5=node5.nextSibling()){
                            QDomElement elem5=node5.toElement();
                            if(elem5.isNull()){
                                   xmlReadingLog+="    Null node here\n";
                                   continue;
                            }
                            xmlReadingLog+="    Found "+elem5.tagName()+" tag\n";
                            if(elem5.tagName()=="Preferred_Starting_Day"){
                                   cn->days_L.append(0);
                                   assert(cn->days_L.count()-1==i);
                                   for(cn->days_L[i]=0; cn->days_L[i]<this->nDaysPerWeek; cn->days_L[i]++)
                                          if(this->daysOfTheWeek[cn->days_L[i]]==elem5.text())
                                                 break;
                                                 
                                   if(cn->days_L[i]>=this->nDaysPerWeek){
                                          QMessageBox::information(parent, tr("FET information"), 
                                                 tr("Constraint ActivitiesPreferredStartingTimes day corrupt for teacher name=%1, students names=%2, subject name=%3, activity tag name=%4, day %5 is inexistent ... ignoring constraint")
                                                 .arg(cn->teacherName)
                                                 .arg(cn->studentsName)
                                                 .arg(cn->subjectName)
                                                 .arg(cn->activityTagName)
                                                 .arg(elem5.text()));
                                          delete cn;
                                          cn=NULL;
                                          //goto corruptConstraintTime;
                                          return NULL;
                                   }
                                                 
                                   assert(cn->days_L[i]<this->nDaysPerWeek);
                                   xmlReadingLog+="    Preferred starting day="+this->daysOfTheWeek[cn->days_L[i]]+"("+CustomFETString::number(i)+")"+"\n";
                            }
                            else if(elem5.tagName()=="Preferred_Starting_Hour"){
                                   cn->hours_L.append(0);
                                   assert(cn->hours_L.count()-1==i);
                                   for(cn->hours_L[i]=0; cn->hours_L[i] < this->nHoursPerDay; cn->hours_L[i]++)
                                          if(this->hoursOfTheDay[cn->hours_L[i]]==elem5.text())
                                                 break;
                                                 
                                   if(cn->hours_L[i]>=this->nHoursPerDay){
                                          QMessageBox::information(parent, tr("FET information"), 
                                                 tr("Constraint ActivitiesPreferredStartingTimes hour corrupt for teacher name=%1, students names=%2, subject name=%3, activity tag name=%4, hour %5 is inexistent ... ignoring constraint")
                                                 .arg(cn->teacherName)
                                                 .arg(cn->studentsName)
                                                 .arg(cn->subjectName)
                                                 .arg(cn->activityTagName)
                                                 .arg(elem5.text()));
                                          delete cn;
                                          cn=NULL;
                                          //goto corruptConstraintTime;
                                          return NULL;
                                   }
                                                 
                                   assert(cn->hours_L[i]>=0 && cn->hours_L[i] < this->nHoursPerDay);
                                   xmlReadingLog+="    Preferred starting hour="+this->hoursOfTheDay[cn->hours_L[i]]+"\n";
                            }
                     }

                     i++;
              }
       }
       assert(i==cn->nPreferredStartingTimes_L);
       return cn;
}

Here is the call graph for this function:

TimeConstraint * Rules::readActivitiesPreferredTimes ( QWidget *  parent,
const QDomElement &  elem3,
FakeString xmlReadingLog 
) [private]

Definition at line 12287 of file rules.cpp.

                                                                                                                       {
       assert(elem3.tagName()=="ConstraintActivitiesPreferredTimes");

       ConstraintActivitiesPreferredStartingTimes* cn=new ConstraintActivitiesPreferredStartingTimes();
       cn->nPreferredStartingTimes_L=0;
       int i;
       /*for(i=0; i<MAX_N_CONSTRAINT_ACTIVITIES_PREFERRED_STARTING_TIMES; i++){
              cn->days[i] = cn->hours[i] = -1;
       }*/
       cn->teacherName="";
       cn->studentsName="";
       cn->subjectName="";
       cn->activityTagName="";
       
       i=0;
       for(QDomNode node4=elem3.firstChild(); !node4.isNull(); node4=node4.nextSibling()){
              QDomElement elem4=node4.toElement();
              if(elem4.isNull()){
                     xmlReadingLog+="    Null node here\n";
                     continue;
              }
              xmlReadingLog+="    Found "+elem4.tagName()+" tag\n";
              if(elem4.tagName()=="Weight"){
                     //cn->weight=customFETStrToDouble(elem4.text());
                     xmlReadingLog+="    Ignoring old tag - weight - making weight percentage=100\n";
                     cn->weightPercentage=100;
              }
              else if(elem4.tagName()=="Weight_Percentage"){
                     cn->weightPercentage=customFETStrToDouble(elem4.text());
                     xmlReadingLog+="    Adding weight percentage="+CustomFETString::number(cn->weightPercentage)+"\n";
              }
              else if(elem4.tagName()=="Active"){
                     if(elem4.text()=="false"){
                            cn->active=false;
                     }
              }
              else if(elem4.tagName()=="Comments"){
                     cn->comments=elem4.text();
              }
              else if(elem4.tagName()=="Compulsory"){
                     if(elem4.text()=="yes"){
                            //cn->compulsory=true;
                            xmlReadingLog+="    Ignoring old tag - Current constraint is compulsory\n";
                            cn->weightPercentage=100;
                     }
                     else{
                            //cn->compulsory=false;
                            xmlReadingLog+="    Old tag - current constraint is not compulsory - making weightPercentage=0%\n";
                            cn->weightPercentage=0;
                     }
              }
              else if(elem4.tagName()=="Teacher_Name"){
                     cn->teacherName=elem4.text();
                     xmlReadingLog+="    Read teacher name="+cn->teacherName+"\n";
              }
              else if(elem4.tagName()=="Students_Name"){
                     cn->studentsName=elem4.text();
                     xmlReadingLog+="    Read students name="+cn->studentsName+"\n";
              }
              else if(elem4.tagName()=="Subject_Name"){
                     cn->subjectName=elem4.text();
                     xmlReadingLog+="    Read subject name="+cn->subjectName+"\n";
              }
              else if(elem4.tagName()=="Subject_Tag_Name"){
                     cn->activityTagName=elem4.text();
                     xmlReadingLog+="    Read activity tag name="+cn->activityTagName+"\n";
              }
              else if(elem4.tagName()=="Activity_Tag_Name"){
                     cn->activityTagName=elem4.text();
                     xmlReadingLog+="    Read activity tag name="+cn->activityTagName+"\n";
              }
              else if(elem4.tagName()=="Number_of_Preferred_Times"){
                     cn->nPreferredStartingTimes_L=elem4.text().toInt();
                     xmlReadingLog+="    Read number of preferred times="+CustomFETString::number(cn->nPreferredStartingTimes_L)+"\n";
              }
              else if(elem4.tagName()=="Preferred_Time"){
                     xmlReadingLog+="    Read: preferred time\n";

                     for(QDomNode node5=elem4.firstChild(); !node5.isNull(); node5=node5.nextSibling()){
                            QDomElement elem5=node5.toElement();
                            if(elem5.isNull()){
                                   xmlReadingLog+="    Null node here\n";
                                   continue;
                            }
                            xmlReadingLog+="    Found "+elem5.tagName()+" tag\n";
                            if(elem5.tagName()=="Preferred_Day"){
                                   cn->days_L.append(0);
                                   assert(cn->days_L.count()-1==i);
                                   for(cn->days_L[i]=0; cn->days_L[i]<this->nDaysPerWeek; cn->days_L[i]++)
                                          if(this->daysOfTheWeek[cn->days_L[i]]==elem5.text())
                                                 break;
                                                 
                                   if(cn->days_L[i]>=this->nDaysPerWeek){
                                          QMessageBox::information(parent, tr("FET information"), 
                                                 tr("Constraint ActivitiesPreferredTimes day corrupt for teacher name=%1, students names=%2, subject name=%3, activity tag name=%4, day %5 is inexistent ... ignoring constraint")
                                                 .arg(cn->teacherName)
                                                 .arg(cn->studentsName)
                                                 .arg(cn->subjectName)
                                                 .arg(cn->activityTagName)
                                                 .arg(elem5.text()));
                                          delete cn;
                                          cn=NULL;
                                          //goto corruptConstraintTime;
                                          return NULL;
                                   }
                                                 
                                   assert(cn->days_L[i]<this->nDaysPerWeek);
                                   xmlReadingLog+="    Preferred day="+this->daysOfTheWeek[cn->days_L[i]]+"("+CustomFETString::number(i)+")"+"\n";
                            }
                            else if(elem5.tagName()=="Preferred_Hour"){
                                   cn->hours_L.append(0);
                                   assert(cn->hours_L.count()-1==i);
                                   for(cn->hours_L[i]=0; cn->hours_L[i] < this->nHoursPerDay; cn->hours_L[i]++)
                                          if(this->hoursOfTheDay[cn->hours_L[i]]==elem5.text())
                                                 break;
                                                 
                                   if(cn->hours_L[i]>=this->nHoursPerDay){
                                          QMessageBox::information(parent, tr("FET information"), 
                                                 tr("Constraint ActivitiesPreferredTimes hour corrupt for teacher name=%1, students names=%2, subject name=%3, activity tag name=%4, hour %5 is inexistent ... ignoring constraint")
                                                 .arg(cn->teacherName)
                                                 .arg(cn->studentsName)
                                                 .arg(cn->subjectName)
                                                 .arg(cn->activityTagName)
                                                 .arg(elem5.text()));
                                          delete cn;
                                          cn=NULL;
                                          //goto corruptConstraintTime;
                                          return NULL;
                                   }
                                                 
                                   assert(cn->hours_L[i]>=0 && cn->hours_L[i] < this->nHoursPerDay);
                                   xmlReadingLog+="    Preferred hour="+this->hoursOfTheDay[cn->hours_L[i]]+"\n";
                            }
                     }

                     i++;
              }
       }
       assert(i==cn->nPreferredStartingTimes_L);
       return cn;
}

Here is the call graph for this function:

TimeConstraint * Rules::readActivitiesPreferredTimeSlots ( QWidget *  parent,
const QDomElement &  elem3,
FakeString xmlReadingLog 
) [private]

Definition at line 12429 of file rules.cpp.

                                                                                                                           {
       assert(elem3.tagName()=="ConstraintActivitiesPreferredTimeSlots");
       ConstraintActivitiesPreferredTimeSlots* cn=new ConstraintActivitiesPreferredTimeSlots();
       cn->p_nPreferredTimeSlots_L=0;
       int i;
       /*for(i=0; i<MAX_N_CONSTRAINT_ACTIVITIES_PREFERRED_TIME_SLOTS; i++){
              cn->p_days[i] = cn->p_hours[i] = -1;
       }*/
       cn->p_teacherName="";
       cn->p_studentsName="";
       cn->p_subjectName="";
       cn->p_activityTagName="";
       
       i=0;
       for(QDomNode node4=elem3.firstChild(); !node4.isNull(); node4=node4.nextSibling()){
              QDomElement elem4=node4.toElement();
              if(elem4.isNull()){
                     xmlReadingLog+="    Null node here\n";
                     continue;
              }
              xmlReadingLog+="    Found "+elem4.tagName()+" tag\n";
              if(elem4.tagName()=="Weight"){
                     //cn->weight=customFETStrToDouble(elem4.text());
                     xmlReadingLog+="    Ignoring old tag - weight - making weight percentage=100\n";
                     cn->weightPercentage=100;
              }
              else if(elem4.tagName()=="Weight_Percentage"){
                     cn->weightPercentage=customFETStrToDouble(elem4.text());
                     xmlReadingLog+="    Adding weight percentage="+CustomFETString::number(cn->weightPercentage)+"\n";
              }
              else if(elem4.tagName()=="Active"){
                     if(elem4.text()=="false"){
                            cn->active=false;
                     }
              }
              else if(elem4.tagName()=="Comments"){
                     cn->comments=elem4.text();
              }
              else if(elem4.tagName()=="Compulsory"){
                     if(elem4.text()=="yes"){
                            //cn->compulsory=true;
                            xmlReadingLog+="    Ignoring old tag - Current constraint is compulsory\n";
                            cn->weightPercentage=100;
                     }
                     else{
                            //cn->compulsory=false;
                            xmlReadingLog+="    Old tag - current constraint is not compulsory - making weightPercentage=0%\n";
                            cn->weightPercentage=0;
                     }
              }
              else if(elem4.tagName()=="Teacher_Name"){
                     cn->p_teacherName=elem4.text();
                     xmlReadingLog+="    Read teacher name="+cn->p_teacherName+"\n";
              }
              else if(elem4.tagName()=="Students_Name"){
                     cn->p_studentsName=elem4.text();
                     xmlReadingLog+="    Read students name="+cn->p_studentsName+"\n";
              }
              else if(elem4.tagName()=="Subject_Name"){
                     cn->p_subjectName=elem4.text();
                     xmlReadingLog+="    Read subject name="+cn->p_subjectName+"\n";
              }
              else if(elem4.tagName()=="Subject_Tag_Name"){
                     cn->p_activityTagName=elem4.text();
                     xmlReadingLog+="    Read activity tag name="+cn->p_activityTagName+"\n";
              }
              else if(elem4.tagName()=="Activity_Tag_Name"){
                     cn->p_activityTagName=elem4.text();
                     xmlReadingLog+="    Read activity tag name="+cn->p_activityTagName+"\n";
              }
              else if(elem4.tagName()=="Number_of_Preferred_Time_Slots"){
                     cn->p_nPreferredTimeSlots_L=elem4.text().toInt();
                     xmlReadingLog+="    Read number of preferred times="+CustomFETString::number(cn->p_nPreferredTimeSlots_L)+"\n";
              }
              else if(elem4.tagName()=="Preferred_Time_Slot"){
                     xmlReadingLog+="    Read: preferred time slot\n";

                     for(QDomNode node5=elem4.firstChild(); !node5.isNull(); node5=node5.nextSibling()){
                            QDomElement elem5=node5.toElement();
                            if(elem5.isNull()){
                                   xmlReadingLog+="    Null node here\n";
                                   continue;
                            }
                            xmlReadingLog+="    Found "+elem5.tagName()+" tag\n";
                            if(elem5.tagName()=="Preferred_Day"){
                                   cn->p_days_L.append(0);
                                   assert(cn->p_days_L.count()-1==i);
                                   for(cn->p_days_L[i]=0; cn->p_days_L[i]<this->nDaysPerWeek; cn->p_days_L[i]++)
                                          if(this->daysOfTheWeek[cn->p_days_L[i]]==elem5.text())
                                                 break;
                                                 
                                   if(cn->p_days_L[i]>=this->nDaysPerWeek){
                                          QMessageBox::information(parent, tr("FET information"), 
                                                 tr("Constraint ActivitiesPreferredTimeSlots day corrupt for teacher name=%1, students names=%2, subject name=%3, activity tag name=%4, day %5 is inexistent ... ignoring constraint")
                                                 .arg(cn->p_teacherName)
                                                 .arg(cn->p_studentsName)
                                                 .arg(cn->p_subjectName)
                                                 .arg(cn->p_activityTagName)
                                                 .arg(elem5.text()));
                                          delete cn;
                                          cn=NULL;
                                          //goto corruptConstraintTime;
                                          return NULL;
                                   }
                                                 
                                   assert(cn->p_days_L[i]<this->nDaysPerWeek);
                                   xmlReadingLog+="    Preferred day="+this->daysOfTheWeek[cn->p_days_L[i]]+"("+CustomFETString::number(i)+")"+"\n";
                            }
                            else if(elem5.tagName()=="Preferred_Hour"){
                                   cn->p_hours_L.append(0);
                                   assert(cn->p_hours_L.count()-1==i);
                                   for(cn->p_hours_L[i]=0; cn->p_hours_L[i] < this->nHoursPerDay; cn->p_hours_L[i]++)
                                          if(this->hoursOfTheDay[cn->p_hours_L[i]]==elem5.text())
                                                 break;
                                                 
                                   if(cn->p_hours_L[i]>=this->nHoursPerDay){
                                          QMessageBox::information(parent, tr("FET information"), 
                                                 tr("Constraint ActivitiesPreferredTimeSlots hour corrupt for teacher name=%1, students names=%2, subject name=%3, activity tag name=%4, hour %5 is inexistent ... ignoring constraint")
                                                 .arg(cn->p_teacherName)
                                                 .arg(cn->p_studentsName)
                                                 .arg(cn->p_subjectName)
                                                 .arg(cn->p_activityTagName)
                                                 .arg(elem5.text()));
                                          delete cn;
                                          cn=NULL;
                                          //goto corruptConstraintTime;
                                          return NULL;
                                   }
                                                 
                                   assert(cn->p_hours_L[i]>=0 && cn->p_hours_L[i] < this->nHoursPerDay);
                                   xmlReadingLog+="    Preferred hour="+this->hoursOfTheDay[cn->p_hours_L[i]]+"\n";
                            }
                     }

                     i++;
              }
       }
       assert(i==cn->p_nPreferredTimeSlots_L);
       return cn;
}

Here is the call graph for this function:

TimeConstraint * Rules::readActivitiesSameStartingDay ( const QDomElement &  elem3,
FakeString xmlReadingLog 
) [private]

Definition at line 9172 of file rules.cpp.

                                                                                                       {
       assert(elem3.tagName()=="ConstraintActivitiesSameStartingDay");
       ConstraintActivitiesSameStartingDay* cn=new ConstraintActivitiesSameStartingDay();
       int n_act=0;
       cn->activitiesId.clear();
       for(QDomNode node4=elem3.firstChild(); !node4.isNull(); node4=node4.nextSibling()){
              QDomElement elem4=node4.toElement();
              if(elem4.isNull()){
                     xmlReadingLog+="    Null node here\n";
                     continue;
              }
              xmlReadingLog+="    Found "+elem4.tagName()+" tag\n";
              if(elem4.tagName()=="Weight_Percentage"){
                     cn->weightPercentage=customFETStrToDouble(elem4.text());
                     xmlReadingLog+="    Adding weight percentage="+CustomFETString::number(cn->weightPercentage)+"\n";
              }
              else if(elem4.tagName()=="Active"){
                     if(elem4.text()=="false"){
                            cn->active=false;
                     }
              }
              else if(elem4.tagName()=="Comments"){
                     cn->comments=elem4.text();
              }
              else if(elem4.tagName()=="Number_of_Activities"){
                     cn->n_activities=elem4.text().toInt();
                     xmlReadingLog+="    Read n_activities="+CustomFETString::number(cn->n_activities)+"\n";
              }
              else if(elem4.tagName()=="Activity_Id"){
                     //cn->activitiesId[n_act]=elem4.text().toInt();
                     cn->activitiesId.append(elem4.text().toInt());
                     assert(n_act==cn->activitiesId.count()-1);
                     xmlReadingLog+="    Read activity id="+CustomFETString::number(cn->activitiesId[n_act])+"\n";
                     n_act++;
              }
       }
       assert(cn->n_activities==n_act);
       return cn;
}

Here is the call graph for this function:

TimeConstraint * Rules::readActivitiesSameStartingHour ( const QDomElement &  elem3,
FakeString xmlReadingLog 
) [private]

Definition at line 9115 of file rules.cpp.

                                                                                                        {
       assert(elem3.tagName()=="ConstraintActivitiesSameStartingHour");
       ConstraintActivitiesSameStartingHour* cn=new ConstraintActivitiesSameStartingHour();
       int n_act=0;
       cn->activitiesId.clear();
       for(QDomNode node4=elem3.firstChild(); !node4.isNull(); node4=node4.nextSibling()){
              QDomElement elem4=node4.toElement();
              if(elem4.isNull()){
                     xmlReadingLog+="    Null node here\n";
                     continue;
              }
              xmlReadingLog+="    Found "+elem4.tagName()+" tag\n";
              if(elem4.tagName()=="Weight"){
                     //cn->weight=customFETStrToDouble(elem4.text());
                     xmlReadingLog+="    Ignoring old tag - weight - making weight percentage=100\n";
                     cn->weightPercentage=100;
              }
              else if(elem4.tagName()=="Weight_Percentage"){
                     cn->weightPercentage=customFETStrToDouble(elem4.text());
                     xmlReadingLog+="    Adding weight percentage="+CustomFETString::number(cn->weightPercentage)+"\n";
              }
              else if(elem4.tagName()=="Active"){
                     if(elem4.text()=="false"){
                            cn->active=false;
                     }
              }
              else if(elem4.tagName()=="Comments"){
                     cn->comments=elem4.text();
              }
              else if(elem4.tagName()=="Compulsory"){
                     if(elem4.text()=="yes"){
                            //cn->compulsory=true;
                            xmlReadingLog+="    Ignoring old tag - Current constraint is compulsory\n";
                            cn->weightPercentage=100;
                     }
                     else{
                            //cn->compulsory=false;
                            xmlReadingLog+="    Old tag - current constraint is not compulsory - making weightPercentage=0%\n";
                            cn->weightPercentage=0;
                     }
              }
              else if(elem4.tagName()=="Number_of_Activities"){
                     cn->n_activities=elem4.text().toInt();
                     xmlReadingLog+="    Read n_activities="+CustomFETString::number(cn->n_activities)+"\n";
              }
              else if(elem4.tagName()=="Activity_Id"){
                     //cn->activitiesId[n_act]=elem4.text().toInt();
                     cn->activitiesId.append(elem4.text().toInt());
                     assert(n_act==cn->activitiesId.count()-1);
                     xmlReadingLog+="    Read activity id="+CustomFETString::number(cn->activitiesId[n_act])+"\n";
                     n_act++;
              }
       }
       assert(cn->n_activities==n_act);
       return cn;
}

Here is the call graph for this function:

TimeConstraint * Rules::readActivitiesSameStartingTime ( const QDomElement &  elem3,
FakeString xmlReadingLog 
) [private]

Definition at line 9058 of file rules.cpp.

                                                                                                        {
       assert(elem3.tagName()=="ConstraintActivitiesSameStartingTime");
       ConstraintActivitiesSameStartingTime* cn=new ConstraintActivitiesSameStartingTime();
       int n_act=0;
       cn->activitiesId.clear();
       for(QDomNode node4=elem3.firstChild(); !node4.isNull(); node4=node4.nextSibling()){
              QDomElement elem4=node4.toElement();
              if(elem4.isNull()){
                     xmlReadingLog+="    Null node here\n";
                     continue;
              }
              xmlReadingLog+="    Found "+elem4.tagName()+" tag\n";
              if(elem4.tagName()=="Weight"){
                     //cn->weight=customFETStrToDouble(elem4.text());
                     xmlReadingLog+="    Ignoring old tag - weight - making weight percentage=100\n";
                     cn->weightPercentage=100;
              }
              else if(elem4.tagName()=="Weight_Percentage"){
                     cn->weightPercentage=customFETStrToDouble(elem4.text());
                     xmlReadingLog+="    Adding weight percentage="+CustomFETString::number(cn->weightPercentage)+"\n";
              }
              else if(elem4.tagName()=="Active"){
                     if(elem4.text()=="false"){
                            cn->active=false;
                     }
              }
              else if(elem4.tagName()=="Comments"){
                     cn->comments=elem4.text();
              }
              else if(elem4.tagName()=="Compulsory"){
                     if(elem4.text()=="yes"){
                            //cn->compulsory=true;
                            xmlReadingLog+="    Ignoring old tag - Current constraint is compulsory\n";
                            cn->weightPercentage=100;
                     }
                     else{
                            //cn->compulsory=false;
                            xmlReadingLog+="    Old tag - current constraint is not compulsory - making weightPercentage=0%\n";
                            cn->weightPercentage=0;
                     }
              }
              else if(elem4.tagName()=="Number_of_Activities"){
                     cn->n_activities=elem4.text().toInt();
                     xmlReadingLog+="    Read n_activities="+CustomFETString::number(cn->n_activities)+"\n";
              }
              else if(elem4.tagName()=="Activity_Id"){
                     //cn->activitiesId[n_act]=elem4.text().toInt();
                     cn->activitiesId.append(elem4.text().toInt());
                     assert(n_act==cn->activitiesId.count()-1);
                     xmlReadingLog+="    Read activity id="+CustomFETString::number(cn->activitiesId[n_act])+"\n";
                     n_act++;
              }
       }
       assert(cn->n_activities==n_act);
       return cn;
}

Here is the call graph for this function:

TimeConstraint * Rules::readActivityEndsStudentsDay ( const QDomElement &  elem3,
FakeString xmlReadingLog 
) [private]

Definition at line 10521 of file rules.cpp.

                                                                                                     {
       assert(elem3.tagName()=="ConstraintActivityEndsStudentsDay");
       ConstraintActivityEndsStudentsDay* cn=new ConstraintActivityEndsStudentsDay();
       for(QDomNode node4=elem3.firstChild(); !node4.isNull(); node4=node4.nextSibling()){
              QDomElement elem4=node4.toElement();
              if(elem4.isNull()){
                     xmlReadingLog+="    Null node here\n";
                     continue;
              }
              xmlReadingLog+="    Found "+elem4.tagName()+" tag\n";
              if(elem4.tagName()=="Weight_Percentage"){
                     cn->weightPercentage=customFETStrToDouble(elem4.text());
                     xmlReadingLog+="    Adding weight percentage="+CustomFETString::number(cn->weightPercentage)+"\n";
              }
              else if(elem4.tagName()=="Active"){
                     if(elem4.text()=="false"){
                            cn->active=false;
                     }
              }
              else if(elem4.tagName()=="Comments"){
                     cn->comments=elem4.text();
              }
              else if(elem4.tagName()=="Activity_Id"){
                     cn->activityId=elem4.text().toInt();
                     xmlReadingLog+="    Read activity id="+CustomFETString::number(cn->activityId)+"\n";
              }
       }
       return cn;
}

Here is the call graph for this function:

SpaceConstraint * Rules::readActivityPreferredRoom ( QWidget *  parent,
const QDomElement &  elem3,
FakeString xmlReadingLog,
bool &  reportUnspecifiedPermanentlyLockedSpace 
) [private]

Definition at line 13507 of file rules.cpp.

                                              {
       assert(elem3.tagName()=="ConstraintActivityPreferredRoom");
       ConstraintActivityPreferredRoom* cn=new ConstraintActivityPreferredRoom();
       cn->permanentlyLocked=false; //default
       bool foundLocked=false;
       for(QDomNode node4=elem3.firstChild(); !node4.isNull(); node4=node4.nextSibling()){
              QDomElement elem4=node4.toElement();
              if(elem4.isNull()){
                     xmlReadingLog+="    Null node here\n";
                     continue;
              }
              xmlReadingLog+="    Found "+elem4.tagName()+" tag\n";
              if(elem4.tagName()=="Weight"){
                     //cn->weight=customFETStrToDouble(elem4.text());
                     xmlReadingLog+="    Ignoring old tag - weight - making weight percentage=100\n";
                     cn->weightPercentage=100;
              }
              else if(elem4.tagName()=="Weight_Percentage"){
                     cn->weightPercentage=customFETStrToDouble(elem4.text());
                     xmlReadingLog+="    Adding weight percentage="+CustomFETString::number(cn->weightPercentage)+"\n";
              }
              else if(elem4.tagName()=="Active"){
                     if(elem4.text()=="false"){
                            cn->active=false;
                     }
              }
              else if(elem4.tagName()=="Comments"){
                     cn->comments=elem4.text();
              }
              else if(elem4.tagName()=="Compulsory"){
                     if(elem4.text()=="yes"){
                            //cn->compulsory=true;
                            xmlReadingLog+="    Ignoring old tag - Current constraint is compulsory\n";
                            cn->weightPercentage=100;
                     }
                     else{
                            //cn->compulsory=false;
                            xmlReadingLog+="    Old tag - current constraint is not compulsory - making weightPercentage=0%\n";
                            cn->weightPercentage=0;
                     }
              }
              else if(elem4.tagName()=="Permanently_Locked"){
                     if(elem4.text()=="true" || elem4.text()=="1" || elem4.text()=="yes"){
                            xmlReadingLog+="    Permanently locked\n";
                            cn->permanentlyLocked=true;
                     }
                     else{
                            if(!(elem4.text()=="no" || elem4.text()=="false" || elem4.text()=="0")){
                                   QMessageBox::warning(parent, tr("FET warning"),
                                          tr("Found constraint activity preferred room with tag permanently locked"
                                          " which is not 'true', 'false', 'yes', 'no', '1' or '0'."
                                          " The tag will be considered false",
                                          "Instructions for translators: please leave the 'true', 'false', 'yes' and 'no' fields untranslated, as they are in English"));
                            }
                            //assert(elem4.text()=="false" || elem4.text()=="0" || elem4.text()=="no");
                            xmlReadingLog+="    Not permanently locked\n";
                            cn->permanentlyLocked=false;
                     }
                     foundLocked=true;
              }

              /*if(elem4.tagName()=="Weight"){
                     cn->weight=customFETStrToDouble(elem4.text());
                     xmlReadingLog+="    Adding weight="+CustomFETString::number(cn->weight)+"\n";
              }
              else if(elem4.tagName()=="Compulsory"){
                     if(elem4.text()=="yes"){
                            cn->compulsory=true;
                            xmlReadingLog+="    Current constraint is compulsory\n";
                     }
                     else{
                            cn->compulsory=false;
                            xmlReadingLog+="    Current constraint is not compulsory\n";
                     }
              }*/
              else if(elem4.tagName()=="Activity_Id"){
                     cn->activityId=elem4.text().toInt();
                     xmlReadingLog+="    Read activity id="+CustomFETString::number(cn->activityId)+"\n";
              }
              else if(elem4.tagName()=="Room"){
                     cn->roomName=elem4.text();
                     xmlReadingLog+="    Read room="+elem4.text()+"\n";
              }
       }
       if(!foundLocked && reportUnspecifiedPermanentlyLockedSpace){
              int t=QMessageBox::information(parent, tr("FET information"),
                     tr("Found constraint activity preferred room, with unspecified tag"
                     " 'permanently locked' - this tag will be set to 'false' by default. You can always modify it"
                     " by editing the constraint in the 'Data' menu")+"\n\n"
                     +tr("Explanation: starting with version 5.8.0 (January 2009), the constraint"
                     " activity preferred room has"
                     " a new tag, 'permanently locked' (true or false)."
                     " It is recommended to make the tag 'permanently locked' true for the constraints you"
                     " need to be not modifiable from the 'Timetable' menu"
                     " and leave this tag false for the constraints you need to be modifiable from the 'Timetable' menu"
                     " (the 'permanently locked' tag can be modified by editing the constraint from the 'Data' menu)."
                     " This way, when viewing the timetable"
                     " and locking/unlocking some activities, you will not unlock the constraints which"
                     " need to be locked all the time."
                     ),
                     tr("Skip rest"), tr("See next"), QString(), 1, 0 );
              if(t==0)
                     reportUnspecifiedPermanentlyLockedSpace=false;
       }

       return cn;
}

Here is the call graph for this function:

SpaceConstraint * Rules::readActivityPreferredRooms ( const QDomElement &  elem3,
FakeString xmlReadingLog 
) [private]

Definition at line 13616 of file rules.cpp.

                                                                                                     {
       assert(elem3.tagName()=="ConstraintActivityPreferredRooms");
       int _n_preferred_rooms=0;
       ConstraintActivityPreferredRooms* cn=new ConstraintActivityPreferredRooms();
       for(QDomNode node4=elem3.firstChild(); !node4.isNull(); node4=node4.nextSibling()){
              QDomElement elem4=node4.toElement();
              if(elem4.isNull()){
                     xmlReadingLog+="    Null node here\n";
                     continue;
              }
              xmlReadingLog+="    Found "+elem4.tagName()+" tag\n";
              if(elem4.tagName()=="Weight"){
                     //cn->weight=customFETStrToDouble(elem4.text());
                     xmlReadingLog+="    Ignoring old tag - weight - making weight percentage=100\n";
                     cn->weightPercentage=100;
              }
              else if(elem4.tagName()=="Weight_Percentage"){
                     cn->weightPercentage=customFETStrToDouble(elem4.text());
                     xmlReadingLog+="    Adding weight percentage="+CustomFETString::number(cn->weightPercentage)+"\n";
              }
              else if(elem4.tagName()=="Active"){
                     if(elem4.text()=="false"){
                            cn->active=false;
                     }
              }
              else if(elem4.tagName()=="Comments"){
                     cn->comments=elem4.text();
              }
              else if(elem4.tagName()=="Compulsory"){
                     if(elem4.text()=="yes"){
                            //cn->compulsory=true;
                            xmlReadingLog+="    Ignoring old tag - Current constraint is compulsory\n";
                            cn->weightPercentage=100;
                     }
                     else{
                            //cn->compulsory=false;
                            xmlReadingLog+="    Old tag - current constraint is not compulsory - making weightPercentage=0%\n";
                            cn->weightPercentage=0;
                     }
              }
              /*if(elem4.tagName()=="Weight"){
                     cn->weight=customFETStrToDouble(elem4.text());
                     xmlReadingLog+="    Adding weight="+CustomFETString::number(cn->weight)+"\n";
              }
              else if(elem4.tagName()=="Compulsory"){
                     if(elem4.text()=="yes"){
                            cn->compulsory=true;
                            xmlReadingLog+="    Current constraint is compulsory\n";
                     }
                     else{
                            cn->compulsory=false;
                            xmlReadingLog+="    Current constraint is not compulsory\n";
                     }
              }*/
              else if(elem4.tagName()=="Activity_Id"){
                     cn->activityId=elem4.text().toInt();
                     xmlReadingLog+="    Read activity id="+CustomFETString::number(cn->activityId)+"\n";
              }
              else if(elem4.tagName()=="Number_of_Preferred_Rooms"){
                     _n_preferred_rooms=elem4.text().toInt();
                     xmlReadingLog+="    Read number of preferred rooms: "+CustomFETString::number(_n_preferred_rooms)+"\n";
                     assert(_n_preferred_rooms>=2);
              }
              else if(elem4.tagName()=="Preferred_Room"){
                     cn->roomsNames.append(elem4.text());
                     xmlReadingLog+="    Read room="+elem4.text()+"\n";
              }
       }
       assert(_n_preferred_rooms==cn->roomsNames.count());
       return cn;
}

Here is the call graph for this function:

TimeConstraint * Rules::readActivityPreferredStartingTime ( QWidget *  parent,
const QDomElement &  elem3,
FakeString xmlReadingLog,
bool &  reportUnspecifiedPermanentlyLockedTime,
bool &  reportUnspecifiedDayOrHourPreferredStartingTime 
) [private]

Definition at line 10353 of file rules.cpp.

                                                                                                    {
       assert(elem3.tagName()=="ConstraintActivityPreferredStartingTime");
       ConstraintActivityPreferredStartingTime* cn=new ConstraintActivityPreferredStartingTime();
       cn->day = cn->hour = -1;
       cn->permanentlyLocked=false; //default false
       bool foundLocked=false;
       for(QDomNode node4=elem3.firstChild(); !node4.isNull(); node4=node4.nextSibling()){
              QDomElement elem4=node4.toElement();
              if(elem4.isNull()){
                     xmlReadingLog+="    Null node here\n";
                     continue;
              }
              xmlReadingLog+="    Found "+elem4.tagName()+" tag\n";
              if(elem4.tagName()=="Weight"){
                     //cn->weight=customFETStrToDouble(elem4.text());
                     xmlReadingLog+="    Ignoring old tag - weight - making weight percentage=100\n";
                     cn->weightPercentage=100;
              }
              else if(elem4.tagName()=="Weight_Percentage"){
                     cn->weightPercentage=customFETStrToDouble(elem4.text());
                     xmlReadingLog+="    Adding weight percentage="+CustomFETString::number(cn->weightPercentage)+"\n";
              }
              else if(elem4.tagName()=="Active"){
                     if(elem4.text()=="false"){
                            cn->active=false;
                     }
              }
              else if(elem4.tagName()=="Comments"){
                     cn->comments=elem4.text();
              }
              else if(elem4.tagName()=="Compulsory"){
                     if(elem4.text()=="yes"){
                            //cn->compulsory=true;
                            xmlReadingLog+="    Ignoring old tag - Current constraint is compulsory\n";
                            cn->weightPercentage=100;
                     }
                     else{
                            //cn->compulsory=false;
                            xmlReadingLog+="    Old tag - current constraint is not compulsory - making weightPercentage=0%\n";
                            cn->weightPercentage=0;
                     }
              }
              else if(elem4.tagName()=="Permanently_Locked"){
                     if(elem4.text()=="true" || elem4.text()=="1" || elem4.text()=="yes"){
                            xmlReadingLog+="    Permanently locked\n";
                            cn->permanentlyLocked=true;
                     }
                     else{
                            if(!(elem4.text()=="no" || elem4.text()=="false" || elem4.text()=="0")){
                                   QMessageBox::warning(parent, tr("FET warning"),
                                          tr("Found constraint activity preferred starting time with tag permanently locked"
                                          " which is not 'true', 'false', 'yes', 'no', '1' or '0'."
                                          " The tag will be considered false",
                                          "Instructions for translators: please leave the 'true', 'false', 'yes' and 'no' fields untranslated, as they are in English"));
                            }
                            //assert(elem4.text()=="false" || elem4.text()=="0" || elem4.text()=="no");
                            xmlReadingLog+="    Not permanently locked\n";
                            cn->permanentlyLocked=false;
                     }
                     foundLocked=true;
              }
              else if(elem4.tagName()=="Activity_Id"){
                     cn->activityId=elem4.text().toInt();
                     xmlReadingLog+="    Read activity id="+CustomFETString::number(cn->activityId)+"\n";
              }
              else if(elem4.tagName()=="Preferred_Day"){
                     for(cn->day=0; cn->day<this->nDaysPerWeek; cn->day++)
                            if(this->daysOfTheWeek[cn->day]==elem4.text())
                                   break;
                     if(cn->day>=this->nDaysPerWeek){
                            QMessageBox::information(parent, tr("FET information"), 
                                   tr("Constraint ActivityPreferredStartingTime day corrupt for activity with id %1, day %2 is inexistent ... ignoring constraint")
                                   .arg(cn->activityId)
                                   .arg(elem4.text()));
                            delete cn;
                            cn=NULL;
                            //goto corruptConstraintTime;
                            return NULL;
                     }
                     assert(cn->day<this->nDaysPerWeek);
                     xmlReadingLog+="    Preferred day="+this->daysOfTheWeek[cn->day]+"\n";
              }
              else if(elem4.tagName()=="Preferred_Hour"){
                     for(cn->hour=0; cn->hour < this->nHoursPerDay; cn->hour++)
                            if(this->hoursOfTheDay[cn->hour]==elem4.text())
                                   break;
                     if(cn->hour>=this->nHoursPerDay){
                            QMessageBox::information(parent, tr("FET information"), 
                                   tr("Constraint ActivityPreferredStartingTime hour corrupt for activity with id %1, hour %2 is inexistent ... ignoring constraint")
                                   .arg(cn->activityId)
                                   .arg(elem4.text()));
                            delete cn;
                            cn=NULL;
                            //goto corruptConstraintTime;
                            return NULL;
                     }
                     assert(cn->hour>=0 && cn->hour < this->nHoursPerDay);
                     xmlReadingLog+="    Preferred hour="+this->hoursOfTheDay[cn->hour]+"\n";
              }
       }
       //crt_constraint=cn;

       if(cn->hour>=0 && cn->day>=0 && !foundLocked && reportUnspecifiedPermanentlyLockedTime){
              int t=QMessageBox::information(parent, tr("FET information"),
                     tr("Found constraint activity preferred starting time, with unspecified tag"
                     " 'permanently locked' - this tag will be set to 'false' by default. You can always modify it"
                     " by editing the constraint in the 'Data' menu")+"\n\n"
                     +tr("Explanation: starting with version 5.8.0 (January 2009), the constraint"
                     " activity preferred starting time has"
                     " a new tag, 'permanently locked' (true or false)."
                     " It is recommended to make the tag 'permanently locked' true for the constraints you"
                     " need to be not modifiable from the 'Timetable' menu"
                     " and leave this tag false for the constraints you need to be modifiable from the 'Timetable' menu"
                     " (the 'permanently locked' tag can be modified by editing the constraint from the 'Data' menu)."
                     " This way, when viewing the timetable"
                     " and locking/unlocking some activities, you will not unlock the constraints which"
                     " need to be locked all the time."
                     ),
                     tr("Skip rest"), tr("See next"), QString(), 1, 0 );
              if(t==0)
                     reportUnspecifiedPermanentlyLockedTime=false;
       }

       if(cn->hour==-1 || cn->day==-1){
              if(reportUnspecifiedDayOrHourPreferredStartingTime){
                     int t=QMessageBox::information(parent, tr("FET information"),
                            tr("Found constraint activity preferred starting time, with unspecified day or hour."
                            " This constraint will be transformed into constraint activity preferred starting times (a set of times, not only one)."
                            " This change is done in FET versions 5.8.1 and higher."
                            ),
                            tr("Skip rest"), tr("See next"), QString(), 1, 0 );
                     if(t==0)
                            reportUnspecifiedDayOrHourPreferredStartingTime=false;
              }
                     
              ConstraintActivityPreferredStartingTimes* cgood=new ConstraintActivityPreferredStartingTimes();
              if(cn->day==-1){
                     cgood->activityId=cn->activityId;
                     cgood->weightPercentage=cn->weightPercentage;
                     cgood->nPreferredStartingTimes_L=this->nDaysPerWeek;
                     for(int i=0; i<cgood->nPreferredStartingTimes_L; i++){
                            /*cgood->days[i]=i;
                            cgood->hours[i]=cn->hour;*/
                            cgood->days_L.append(i);
                            cgood->hours_L.append(cn->hour);
                     }
              }
              else{
                     assert(cn->hour==-1);
                     cgood->activityId=cn->activityId;
                     cgood->weightPercentage=cn->weightPercentage;
                     cgood->nPreferredStartingTimes_L=this->nHoursPerDay;
                     for(int i=0; i<cgood->nPreferredStartingTimes_L; i++){
                            /*cgood->days[i]=cn->day;
                            cgood->hours[i]=i;*/
                            cgood->days_L.append(cn->day);
                            cgood->hours_L.append(i);
                     }
              }
              
              delete cn;
              return cgood;
       }
       
       return cn;
}

Here is the call graph for this function:

TimeConstraint * Rules::readActivityPreferredStartingTimes ( QWidget *  parent,
const QDomElement &  elem3,
FakeString xmlReadingLog 
) [private]

Definition at line 11214 of file rules.cpp.

                                                                                                                             {
       assert(elem3.tagName()=="ConstraintActivityPreferredStartingTimes");
       ConstraintActivityPreferredStartingTimes* cn=new ConstraintActivityPreferredStartingTimes();
       cn->nPreferredStartingTimes_L=0;
       int i;
       /*for(i=0; i<MAX_N_CONSTRAINT_ACTIVITY_PREFERRED_STARTING_TIMES; i++){
              cn->days[i] = cn->hours[i] = -1;
       }*/
       i=0;
       for(QDomNode node4=elem3.firstChild(); !node4.isNull(); node4=node4.nextSibling()){
              QDomElement elem4=node4.toElement();
              if(elem4.isNull()){
                     xmlReadingLog+="    Null node here\n";
                     continue;
              }
              xmlReadingLog+="    Found "+elem4.tagName()+" tag\n";
              if(elem4.tagName()=="Weight"){
                     //cn->weight=customFETStrToDouble(elem4.text());
                     xmlReadingLog+="    Ignoring old tag - weight - making weight percentage=100\n";
                     cn->weightPercentage=100;
              }
              else if(elem4.tagName()=="Weight_Percentage"){
                     cn->weightPercentage=customFETStrToDouble(elem4.text());
                     xmlReadingLog+="    Adding weight percentage="+CustomFETString::number(cn->weightPercentage)+"\n";
              }
              else if(elem4.tagName()=="Active"){
                     if(elem4.text()=="false"){
                            cn->active=false;
                     }
              }
              else if(elem4.tagName()=="Comments"){
                     cn->comments=elem4.text();
              }
              else if(elem4.tagName()=="Compulsory"){
                     if(elem4.text()=="yes"){
                            //cn->compulsory=true;
                            xmlReadingLog+="    Ignoring old tag - Current constraint is compulsory\n";
                            cn->weightPercentage=100;
                     }
                     else{
                            //cn->compulsory=false;
                            xmlReadingLog+="    Old tag - current constraint is not compulsory - making weightPercentage=0%\n";
                            cn->weightPercentage=0;
                     }
              }
              else if(elem4.tagName()=="Activity_Id"){
                     cn->activityId=elem4.text().toInt();
                     xmlReadingLog+="    Read activity id="+CustomFETString::number(cn->activityId)+"\n";
              }
              else if(elem4.tagName()=="Number_of_Preferred_Starting_Times"){
                     cn->nPreferredStartingTimes_L=elem4.text().toInt();
                     xmlReadingLog+="    Read number of preferred starting times="+CustomFETString::number(cn->nPreferredStartingTimes_L)+"\n";
              }
              else if(elem4.tagName()=="Preferred_Starting_Time"){
                     xmlReadingLog+="    Read: preferred starting time\n";

                     for(QDomNode node5=elem4.firstChild(); !node5.isNull(); node5=node5.nextSibling()){
                            QDomElement elem5=node5.toElement();
                            if(elem5.isNull()){
                                   xmlReadingLog+="    Null node here\n";
                                   continue;
                            }
                            xmlReadingLog+="    Found "+elem5.tagName()+" tag\n";
                            if(elem5.tagName()=="Preferred_Starting_Day"){
                                   cn->days_L.append(0);
                                   assert(cn->days_L.count()-1==i);
                                   for(cn->days_L[i]=0; cn->days_L[i]<this->nDaysPerWeek; cn->days_L[i]++)
                                          if(this->daysOfTheWeek[cn->days_L[i]]==elem5.text())
                                                 break;

                                   if(cn->days_L[i]>=this->nDaysPerWeek){
                                          QMessageBox::information(parent, tr("FET information"), 
                                                 tr("Constraint ActivityPreferredStartingTimes day corrupt for activity with id %1, day %2 is inexistent ... ignoring constraint")
                                                 .arg(cn->activityId)
                                                 .arg(elem5.text()));
                                          delete cn;
                                          cn=NULL;
                                          //goto corruptConstraintTime;
                                          return NULL;
                                   }
              
                                   assert(cn->days_L[i]<this->nDaysPerWeek);
                                   xmlReadingLog+="    Preferred starting day="+this->daysOfTheWeek[cn->days_L[i]]+"("+CustomFETString::number(i)+")"+"\n";
                            }
                            else if(elem5.tagName()=="Preferred_Starting_Hour"){
                                   cn->hours_L.append(0);
                                   assert(cn->hours_L.count()-1==i);
                                   for(cn->hours_L[i]=0; cn->hours_L[i] < this->nHoursPerDay; cn->hours_L[i]++)
                                          if(this->hoursOfTheDay[cn->hours_L[i]]==elem5.text())
                                                 break;
                                   
                                   if(cn->hours_L[i]>=this->nHoursPerDay){
                                          QMessageBox::information(parent, tr("FET information"), 
                                                 tr("Constraint ActivityPreferredStartingTimes hour corrupt for activity with id %1, hour %2 is inexistent ... ignoring constraint")
                                                 .arg(cn->activityId)
                                                 .arg(elem5.text()));
                                          delete cn;
                                          cn=NULL;
                                          //goto corruptConstraintTime;
                                          return NULL;
                                   }
                                   
                                   assert(cn->hours_L[i]>=0 && cn->hours_L[i] < this->nHoursPerDay);
                                   xmlReadingLog+="    Preferred starting hour="+this->hoursOfTheDay[cn->hours_L[i]]+"\n";
                            }
                     }

                     i++;
              }
       }
       assert(i==cn->nPreferredStartingTimes_L);
       return cn;
}

Here is the call graph for this function:

TimeConstraint * Rules::readActivityPreferredTime ( QWidget *  parent,
const QDomElement &  elem3,
FakeString xmlReadingLog,
bool &  reportUnspecifiedPermanentlyLockedTime,
bool &  reportUnspecifiedDayOrHourPreferredStartingTime 
) [private]

Definition at line 10184 of file rules.cpp.

                                                                                                    {
       assert(elem3.tagName()=="ConstraintActivityPreferredTime");

       ConstraintActivityPreferredStartingTime* cn=new ConstraintActivityPreferredStartingTime();
       cn->day = cn->hour = -1;
       cn->permanentlyLocked=false; //default not locked
       bool foundLocked=false;
       for(QDomNode node4=elem3.firstChild(); !node4.isNull(); node4=node4.nextSibling()){
              QDomElement elem4=node4.toElement();
              if(elem4.isNull()){
                     xmlReadingLog+="    Null node here\n";
                     continue;
              }
              xmlReadingLog+="    Found "+elem4.tagName()+" tag\n";
              if(elem4.tagName()=="Weight"){
                     //cn->weight=customFETStrToDouble(elem4.text());
                     xmlReadingLog+="    Ignoring old tag - weight - making weight percentage=100\n";
                     cn->weightPercentage=100;
              }
              else if(elem4.tagName()=="Weight_Percentage"){
                     cn->weightPercentage=customFETStrToDouble(elem4.text());
                     xmlReadingLog+="    Adding weight percentage="+CustomFETString::number(cn->weightPercentage)+"\n";
              }
              else if(elem4.tagName()=="Active"){
                     if(elem4.text()=="false"){
                            cn->active=false;
                     }
              }
              else if(elem4.tagName()=="Comments"){
                     cn->comments=elem4.text();
              }
              else if(elem4.tagName()=="Compulsory"){
                     if(elem4.text()=="yes"){
                            //cn->compulsory=true;
                            xmlReadingLog+="    Ignoring old tag - Current constraint is compulsory\n";
                            cn->weightPercentage=100;
                     }
                     else{
                            //cn->compulsory=false;
                            xmlReadingLog+="    Old tag - current constraint is not compulsory - making weightPercentage=0%\n";
                            cn->weightPercentage=0;
                     }
              }
              else if(elem4.tagName()=="Permanently_Locked"){
                     if(elem4.text()=="true" || elem4.text()=="1" || elem4.text()=="yes"){
                            xmlReadingLog+="    Permanently locked\n";
                            cn->permanentlyLocked=true;
                     }
                     else{
                            if(!(elem4.text()=="no" || elem4.text()=="false" || elem4.text()=="0")){
                                   QMessageBox::warning(parent, tr("FET warning"),
                                          tr("Found constraint activity preferred starting time with tag permanently locked"
                                          " which is not 'true', 'false', 'yes', 'no', '1' or '0'."
                                          " The tag will be considered false",
                                          "Instructions for translators: please leave the 'true', 'false', 'yes' and 'no' fields untranslated, as they are in English"));
                            }
                            //assert(elem4.text()=="false" || elem4.text()=="0" || elem4.text()=="no");
                            xmlReadingLog+="    Not permanently locked\n";
                            cn->permanentlyLocked=false;
                     }
                     foundLocked=true;
              }
              else if(elem4.tagName()=="Activity_Id"){
                     cn->activityId=elem4.text().toInt();
                     xmlReadingLog+="    Read activity id="+CustomFETString::number(cn->activityId)+"\n";
              }
              else if(elem4.tagName()=="Preferred_Day"){
                     for(cn->day=0; cn->day<this->nDaysPerWeek; cn->day++)
                            if(this->daysOfTheWeek[cn->day]==elem4.text())
                                   break;
                     if(cn->day>=this->nDaysPerWeek){
                            QMessageBox::information(parent, tr("FET information"), 
                                   tr("Constraint ActivityPreferredTime day corrupt for activity with id %1, day %2 is inexistent ... ignoring constraint")
                                   .arg(cn->activityId)
                                   .arg(elem4.text()));
                            delete cn;
                            cn=NULL;
                            //goto corruptConstraintTime;
                            return NULL;
                     }
                     assert(cn->day<this->nDaysPerWeek);
                     xmlReadingLog+="    Preferred day="+this->daysOfTheWeek[cn->day]+"\n";
              }
              else if(elem4.tagName()=="Preferred_Hour"){
                     for(cn->hour=0; cn->hour < this->nHoursPerDay; cn->hour++)
                            if(this->hoursOfTheDay[cn->hour]==elem4.text())
                                   break;
                     if(cn->hour>=this->nHoursPerDay){
                            QMessageBox::information(parent, tr("FET information"), 
                                   tr("Constraint ActivityPreferredTime hour corrupt for activity with id %1, hour %2 is inexistent ... ignoring constraint")
                                   .arg(cn->activityId)
                                   .arg(elem4.text()));
                            delete cn;
                            cn=NULL;
                            //goto corruptConstraintTime;
                            return NULL;
                     }
                     assert(cn->hour>=0 && cn->hour < this->nHoursPerDay);
                     xmlReadingLog+="    Preferred hour="+this->hoursOfTheDay[cn->hour]+"\n";
              }
       }
       //crt_constraint=cn;

       if(cn->hour>=0 && cn->day>=0 && !foundLocked && reportUnspecifiedPermanentlyLockedTime){
              int t=QMessageBox::information(parent, tr("FET information"),
                     tr("Found constraint activity preferred starting time, with unspecified tag"
                     " 'permanently locked' - this tag will be set to 'false' by default. You can always modify it"
                     " by editing the constraint in the 'Data' menu")+"\n\n"
                     +tr("Explanation: starting with version 5.8.0 (January 2009), the constraint"
                     " activity preferred starting time has"
                     " a new tag, 'permanently locked' (true or false)."
                     " It is recommended to make the tag 'permanently locked' true for the constraints you"
                     " need to be not modifiable from the 'Timetable' menu"
                     " and leave this tag false for the constraints you need to be modifiable from the 'Timetable' menu"
                     " (the 'permanently locked' tag can be modified by editing the constraint from the 'Data' menu)."
                     " This way, when viewing the timetable"
                     " and locking/unlocking some activities, you will not unlock the constraints which"
                     " need to be locked all the time."
                     ),
                     tr("Skip rest"), tr("See next"), QString(), 1, 0 );
              if(t==0)
                     reportUnspecifiedPermanentlyLockedTime=false;
       }
       
       if(cn->hour==-1 || cn->day==-1){
              if(reportUnspecifiedDayOrHourPreferredStartingTime){
                     int t=QMessageBox::information(parent, tr("FET information"),
                            tr("Found constraint activity preferred starting time, with unspecified day or hour."
                            " This constraint will be transformed into constraint activity preferred starting times (a set of times, not only one)."
                            " This change is done in FET versions 5.8.1 and higher."
                            ),
                            tr("Skip rest"), tr("See next"), QString(), 1, 0 );
                     if(t==0)
                            reportUnspecifiedDayOrHourPreferredStartingTime=false;
              }
                     
              ConstraintActivityPreferredStartingTimes* cgood=new ConstraintActivityPreferredStartingTimes();
              if(cn->day==-1){
                     cgood->activity