void BuildingsForm::modifyBuilding() { int valv=buildingsListWidget->verticalScrollBar()->value(); int valh=buildingsListWidget->horizontalScrollBar()->value(); int ci=buildingsListWidget->currentRow(); if(ci<0){ QMessageBox::information(this, tr("FET information"), tr("Invalid selected building")); return; } Building* bu=visibleBuildingsList.at(ci); ModifyBuildingForm form(this, bu->name); setParentAndOtherThings(&form, this); form.exec(); filterChanged(); buildingsListWidget->verticalScrollBar()->setValue(valv); buildingsListWidget->horizontalScrollBar()->setValue(valh); if(ci>=buildingsListWidget->count()) ci=buildingsListWidget->count()-1; if(ci>=0) buildingsListWidget->setCurrentRow(ci); }
void ConstraintStudentsSetIntervalMaxDaysPerWeekForm::modifyConstraint() { int valv=constraintsListWidget->verticalScrollBar()->value(); int valh=constraintsListWidget->horizontalScrollBar()->value(); int i=constraintsListWidget->currentRow(); if(i<0){ QMessageBox::information(this, tr("FET information"), tr("Invalid selected constraint")); return; } TimeConstraint* ctr=this->visibleConstraintsList.at(i); ModifyConstraintStudentsSetIntervalMaxDaysPerWeekForm form(this, (ConstraintStudentsSetIntervalMaxDaysPerWeek*)ctr); setParentAndOtherThings(&form, this); form.exec(); filterChanged(); constraintsListWidget->verticalScrollBar()->setValue(valv); constraintsListWidget->horizontalScrollBar()->setValue(valh); if(i>=constraintsListWidget->count()) i=constraintsListWidget->count()-1; if(i>=0) constraintsListWidget->setCurrentRow(i); else this->constraintChanged(-1); }
void TimetableGenerateForm::seeInitialOrder() { QString s=initialOrderOfActivities; //show the message in a dialog QDialog dialog(this); dialog.setWindowTitle(tr("FET - information about initial order of evaluation of activities")); QVBoxLayout* vl=new QVBoxLayout(&dialog); QPlainTextEdit* te=new QPlainTextEdit(); te->setPlainText(s); te->setReadOnly(true); QPushButton* pb=new QPushButton(tr("OK")); QHBoxLayout* hl=new QHBoxLayout(0); hl->addStretch(1); hl->addWidget(pb); vl->addWidget(te); vl->addLayout(hl); connect(pb, SIGNAL(clicked()), &dialog, SLOT(close())); dialog.resize(700,500); centerWidgetOnScreen(&dialog); restoreFETDialogGeometry(&dialog, settingsName); setParentAndOtherThings(&dialog, this); dialog.exec(); saveFETDialogGeometry(&dialog, settingsName); }
void ModifySubactivityForm::help() { QString s; s+=tr("Abbreviations in this dialog:"); s+="\n\n"; s+=tr("'Students' (the text near the spin box), means 'Number of students (-1 for automatic)'"); s+="\n"; //show the message in a dialog QDialog dialog(this); dialog.setWindowTitle(tr("FET - help on modifying subactivity(ies)")); QVBoxLayout* vl=new QVBoxLayout(&dialog); QPlainTextEdit* te=new QPlainTextEdit(); te->setPlainText(s); te->setReadOnly(true); QPushButton* pb=new QPushButton(tr("OK")); QHBoxLayout* hl=new QHBoxLayout(0); hl->addStretch(1); hl->addWidget(pb); vl->addWidget(te); vl->addLayout(hl); connect(pb, SIGNAL(clicked()), &dialog, SLOT(close())); dialog.resize(600,470); centerWidgetOnScreen(&dialog); setParentAndOtherThings(&dialog, this); dialog.exec(); }
void SubgroupsForm::addSubgroup() { if(yearsListWidget->currentRow()<0){ QMessageBox::information(this, tr("FET information"), tr("Invalid selected year")); return; } QString yearName=yearsListWidget->currentItem()->text(); int yearIndex=gt.rules.searchYear(yearName); assert(yearIndex>=0); if(groupsListWidget->currentRow()<0){ QMessageBox::information(this, tr("FET information"), tr("Invalid selected group")); return; } QString groupName=groupsListWidget->currentItem()->text(); int groupIndex=gt.rules.searchGroup(yearName, groupName); assert(groupIndex>=0); AddStudentsSubgroupForm form(this, yearName, groupName); setParentAndOtherThings(&form, this); form.exec(); groupChanged(groupsListWidget->currentItem()->text()); int i=subgroupsListWidget->count()-1; if(i>=0) subgroupsListWidget->setCurrentRow(i); }
void ConstraintSubactivitiesPreferredStartingTimesForm::modifyConstraint() { int valv=constraintsListWidget->verticalScrollBar()->value(); int valh=constraintsListWidget->horizontalScrollBar()->value(); int i=constraintsListWidget->currentRow(); if(i<0) { QMessageBox::information(this, tr("FET information"), tr("Invalid selected constraint")); return; } TimeConstraint* ctr=this->visibleConstraintsList.at(i); ModifyConstraintSubactivitiesPreferredStartingTimesForm form(this, (ConstraintSubactivitiesPreferredStartingTimes*)ctr); setParentAndOtherThings(&form, this); form.exec(); this->refreshConstraintsListWidget(); constraintsListWidget->verticalScrollBar()->setValue(valv); constraintsListWidget->horizontalScrollBar()->setValue(valh); if(i>=constraintsListWidget->count()) i=constraintsListWidget->count()-1; if(i>=0) constraintsListWidget->setCurrentRow(i); else this->constraintChanged(-1); }
void TimetableGenerateForm::seeImpossible() { QString s; myMutex.lock(); s+=TimetableGenerateForm::tr("Information relating difficult to schedule activities:"); s+="\n\n"; s+=TimetableGenerateForm::tr("Please check the constraints related to the last " "activities in the list below, which might be difficult to schedule:"); s+="\n\n"; s+=TimetableGenerateForm::tr("Here are the placed activities which lead to a difficulty, " "in order from the first one to the last (the last one FET failed to schedule " "and the last ones are difficult):"); s+="\n\n"; for(int i=0; i<gen.nDifficultActivities; i++){ int ai=gen.difficultActivities[i]; s+=TimetableGenerateForm::tr("No: %1").arg(i+1); s+=", "; s+=TimetableGenerateForm::tr("Id: %1 (%2)", "%1 is id of activity, %2 is detailed description of activity") .arg(gt.rules.internalActivitiesList[ai].id) .arg(getActivityDetailedDescription(gt.rules, gt.rules.internalActivitiesList[ai].id)); s+="\n"; } myMutex.unlock(); //show the message in a dialog QDialog dialog(this); dialog.setWindowTitle(tr("FET - information about difficult activities")); QVBoxLayout* vl=new QVBoxLayout(&dialog); QPlainTextEdit* te=new QPlainTextEdit(); te->setPlainText(s); te->setReadOnly(true); QPushButton* pb=new QPushButton(tr("OK")); QHBoxLayout* hl=new QHBoxLayout(0); hl->addStretch(1); hl->addWidget(pb); vl->addWidget(te); vl->addLayout(hl); connect(pb, SIGNAL(clicked()), &dialog, SLOT(close())); dialog.resize(700,500); centerWidgetOnScreen(&dialog); restoreFETDialogGeometry(&dialog, settingsName); setParentAndOtherThings(&dialog, this); dialog.exec(); saveFETDialogGeometry(&dialog, settingsName); }
void ConstraintActivitiesOccupyMaxTimeSlotsFromSelectionForm::addConstraint() { AddConstraintActivitiesOccupyMaxTimeSlotsFromSelectionForm form(this); setParentAndOtherThings(&form, this); form.exec(); filterChanged(); constraintsListWidget->setCurrentRow(constraintsListWidget->count()-1); }
void ConstraintActivityEndsStudentsDayForm::addConstraint() { AddConstraintActivityEndsStudentsDayForm form(this); setParentAndOtherThings(&form, this); form.exec(); filterChanged(); constraintsListWidget->setCurrentRow(constraintsListWidget->count()-1); }
void ConstraintThreeActivitiesGroupedForm::addConstraint() { AddConstraintThreeActivitiesGroupedForm form(this); setParentAndOtherThings(&form, this); form.exec(); filterChanged(); constraintsListWidget->setCurrentRow(constraintsListWidget->count()-1); }
void ConstraintActivitiesMaxSimultaneousInSelectedTimeSlotsForm::addConstraint() { AddConstraintActivitiesMaxSimultaneousInSelectedTimeSlotsForm form(this); setParentAndOtherThings(&form, this); form.exec(); filterChanged(); constraintsListWidget->setCurrentRow(constraintsListWidget->count()-1); }
void ConstraintStudentsSetMinGapsBetweenBuildingChangesForm::addConstraint() { AddConstraintStudentsSetMinGapsBetweenBuildingChangesForm form(this); setParentAndOtherThings(&form, this); form.exec(); filterChanged(); constraintsListWidget->setCurrentRow(constraintsListWidget->count()-1); }
void ConstraintSubactivitiesPreferredStartingTimesForm::addConstraint() { AddConstraintSubactivitiesPreferredStartingTimesForm form(this); setParentAndOtherThings(&form, this); form.exec(); this->refreshConstraintsListWidget(); constraintsListWidget->setCurrentRow(constraintsListWidget->count()-1); }
void BuildingsForm::addBuilding() { AddBuildingForm addBuildingForm(this); setParentAndOtherThings(&addBuildingForm, this); addBuildingForm.exec(); filterChanged(); buildingsListWidget->setCurrentRow(buildingsListWidget->count()-1); }
void ConstraintTeacherActivityTagMaxHoursDailyForm::addConstraint() { AddConstraintTeacherActivityTagMaxHoursDailyForm form(this); setParentAndOtherThings(&form, this); form.exec(); filterChanged(); constraintsListWidget->setCurrentRow(constraintsListWidget->count()-1); }
void ConstraintTeacherNotAvailableTimesForm::addConstraint() { AddConstraintTeacherNotAvailableTimesForm form(this); setParentAndOtherThings(&form, this); form.exec(); filterChanged(); constraintsListWidget->setCurrentRow(constraintsListWidget->count()-1); }
void ConstraintActivitiesSameRoomIfConsecutiveForm::addConstraint() { AddConstraintActivitiesSameRoomIfConsecutiveForm form(this); setParentAndOtherThings(&form, this); form.exec(); filterChanged(); constraintsListWidget->setCurrentRow(constraintsListWidget->count()-1); }
void ConstraintTeacherHomeRoomsForm::addConstraint() { AddConstraintTeacherHomeRoomsForm form(this); setParentAndOtherThings(&form, this); form.exec(); this->refreshConstraintsListWidget(); constraintsListWidget->setCurrentRow(constraintsListWidget->count()-1); }
void ConstraintTeachersMaxDaysPerWeekForm::addConstraint() { AddConstraintTeachersMaxDaysPerWeekForm form(this); setParentAndOtherThings(&form, this); form.exec(); filterChanged(); constraintsListWidget->setCurrentRow(constraintsListWidget->count()-1); }
void ConstraintSubjectActivityTagPreferredRoomForm::addConstraint() { AddConstraintSubjectActivityTagPreferredRoomForm form(this); setParentAndOtherThings(&form, this); form.exec(); filterChanged(); constraintsListWidget->setCurrentRow(constraintsListWidget->count()-1); }
void ConstraintStudentsMaxHoursContinuouslyForm::addConstraint() { AddConstraintStudentsMaxHoursContinuouslyForm form(this); setParentAndOtherThings(&form, this); form.exec(); filterChanged(); constraintsListWidget->setCurrentRow(constraintsListWidget->count()-1); }
void YearsForm::divideYear() { if(yearsListWidget->currentRow()<0){ QMessageBox::information(this, tr("FET information"), tr("Invalid selected year")); return; } QString yearName=yearsListWidget->currentItem()->text(); SplitYearForm form(this, yearName); setParentAndOtherThings(&form, this); form.exec(); }
void SubgroupsForm::modifySubgroup() { if(yearsListWidget->currentRow()<0){ QMessageBox::information(this, tr("FET information"), tr("Invalid selected year")); return; } QString yearName=yearsListWidget->currentItem()->text(); int yearIndex=gt.rules.searchYear(yearName); assert(yearIndex>=0); if(groupsListWidget->currentRow()<0){ QMessageBox::information(this, tr("FET information"), tr("Invalid selected group")); return; } QString groupName=groupsListWidget->currentItem()->text(); int groupIndex=gt.rules.searchGroup(yearName, groupName); assert(groupIndex>=0); int q=subgroupsListWidget->currentRow(); int valv=subgroupsListWidget->verticalScrollBar()->value(); int valh=subgroupsListWidget->horizontalScrollBar()->value(); if(subgroupsListWidget->currentRow()<0){ QMessageBox::information(this, tr("FET information"), tr("Invalid selected subgroup")); return; } QString subgroupName=subgroupsListWidget->currentItem()->text(); int subgroupIndex=gt.rules.searchSubgroup(yearName, groupName, subgroupName); assert(subgroupIndex>=0); StudentsSet* sset=gt.rules.searchStudentsSet(subgroupName); assert(sset!=NULL); int numberOfStudents=sset->numberOfStudents; ModifyStudentsSubgroupForm form(this, yearName, groupName, subgroupName, numberOfStudents); setParentAndOtherThings(&form, this); form.exec(); groupChanged(groupName); subgroupsListWidget->verticalScrollBar()->setValue(valv); subgroupsListWidget->horizontalScrollBar()->setValue(valh); if(q>=subgroupsListWidget->count()) q=subgroupsListWidget->count()-1; if(q>=0) subgroupsListWidget->setCurrentRow(q); else subgroupTextEdit->setPlainText(QString("")); }
void YearsForm::addYear() { AddStudentsYearForm form(this); setParentAndOtherThings(&form, this); form.exec(); yearsListWidget->clear(); for(int i=0; i<gt.rules.yearsList.size(); i++){ StudentsYear* year=gt.rules.yearsList[i]; yearsListWidget->addItem(year->name); } int i=yearsListWidget->count()-1; if(i>=0) yearsListWidget->setCurrentRow(i); }
void ModifyActivityForm::help() { QString s; s+=tr("Abbreviations in this dialog:"); s+="\n\n"; s+=tr("'Students' (the text near the spin box), means 'Number of students (-1 for automatic)'"); s+="\n"; s+=tr("'Split' means 'Is split into ... activities per week'. This value cannot be changed." " If you need to modify it, please remove the corresponding activities and add a new split activity."); s+="\n"; s+=tr("The 'Duration' spin box and the 'Active' check box refer to each component of current activity, you can change " "them for each component, separately, by selecting the corresponding tab in the tab widget."); //show the message in a dialog QDialog dialog(this); dialog.setWindowTitle(tr("FET - help on modifying activity(ies)")); QVBoxLayout* vl=new QVBoxLayout(&dialog); QPlainTextEdit* te=new QPlainTextEdit(); te->setPlainText(s); te->setReadOnly(true); QPushButton* pb=new QPushButton(tr("OK")); QHBoxLayout* hl=new QHBoxLayout(0); hl->addStretch(1); hl->addWidget(pb); vl->addWidget(te); vl->addLayout(hl); connect(pb, SIGNAL(clicked()), &dialog, SLOT(close())); dialog.resize(600,470); centerWidgetOnScreen(&dialog); setParentAndOtherThings(&dialog, this); dialog.exec(); }
void YearsForm::modifyYear() { int q=yearsListWidget->currentRow(); int valv=yearsListWidget->verticalScrollBar()->value(); int valh=yearsListWidget->horizontalScrollBar()->value(); if(yearsListWidget->currentRow()<0){ QMessageBox::information(this, tr("FET information"), tr("Invalid selected year")); return; } QString yearName=yearsListWidget->currentItem()->text(); StudentsSet* sset=gt.rules.searchStudentsSet(yearName); assert(sset!=NULL); int numberOfStudents=sset->numberOfStudents; ModifyStudentsYearForm form(this, yearName, numberOfStudents); setParentAndOtherThings(&form, this); form.exec(); yearsListWidget->clear(); for(int i=0; i<gt.rules.yearsList.size(); i++){ StudentsYear* year=gt.rules.yearsList[i]; yearsListWidget->addItem(year->name); } yearsListWidget->verticalScrollBar()->setValue(valv); yearsListWidget->horizontalScrollBar()->setValue(valh); if(q>=yearsListWidget->count()) q=yearsListWidget->count()-1; if(q>=0) yearsListWidget->setCurrentRow(q); else detailsTextEdit->setPlainText(QString("")); }
void TimetableGenerateForm::stopHighest() { if(!simulation_running){ return; } simulation_running=false; myMutex.lock(); gen.abortOptimization=true; myMutex.unlock(); myMutex.lock(); Solution& c=highestStageSolution; //needed to find the conflicts strings QString tmp; c.fitness(gt.rules, &tmp); TimetableExport::getStudentsTimetable(c); TimetableExport::getTeachersTimetable(c); TimetableExport::getRoomsTimetable(c); //update the string representing the conflicts conflictsStringTitle=TimetableGenerateForm::tr("Conflicts", "Title of dialog"); conflictsString=""; conflictsString+=TimetableGenerateForm::tr("Total conflicts:"); conflictsString+=" "; conflictsString+=CustomFETString::number(c.conflictsTotal); conflictsString+="\n"; conflictsString+=TimetableGenerateForm::tr("Conflicts listing (in decreasing order):"); conflictsString+="\n"; foreach(QString t, c.conflictsDescriptionList) conflictsString+=t+"\n"; TimetableExport::writeHighestStageResults(this); QString s=TimetableGenerateForm::tr("Simulation interrupted! FET could not find a timetable." " Maybe you can consider lowering the constraints."); s+=" "; QString kk; kk=FILE_SEP; if(INPUT_FILENAME_XML=="") kk.append("unnamed"); else{ kk.append(INPUT_FILENAME_XML.right(INPUT_FILENAME_XML.length()-INPUT_FILENAME_XML.lastIndexOf(FILE_SEP)-1)); if(kk.right(4)==".fet") kk=kk.left(kk.length()-4); } kk.append("-highest"); s+=TimetableGenerateForm::tr("The partial highest-stage results were saved in the directory %1") .arg(QDir::toNativeSeparators(OUTPUT_DIR+FILE_SEP+"timetables"+kk)); s+="\n\n"; s+=TimetableGenerateForm::tr("Additional information relating impossible to schedule activities:"); s+="\n\n"; s+=tr("FET managed to schedule correctly the first %1 most difficult activities." " You can see initial order of placing the activities in the generate dialog. The activity which might cause problems" " might be the next activity in the initial order of evaluation. This activity is listed below:") .arg(maxActivitiesPlaced); s+="\n\n"; s+=tr("Please check constraints related to following possibly problematic activity (or teacher(s), or students set(s)):"); s+="\n"; s+="-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "; s+="\n"; if(maxActivitiesPlaced>=0 && maxActivitiesPlaced<gt.rules.nInternalActivities && initialOrderOfActivitiesIndices[maxActivitiesPlaced]>=0 && initialOrderOfActivitiesIndices[maxActivitiesPlaced]<gt.rules.nInternalActivities){ int ai=initialOrderOfActivitiesIndices[maxActivitiesPlaced]; s+=TimetableGenerateForm::tr("Id: %1 (%2)", "%1 is id of activity, %2 is detailed description of activity") .arg(gt.rules.internalActivitiesList[ai].id) .arg(getActivityDetailedDescription(gt.rules, gt.rules.internalActivitiesList[ai].id)); } else s+=tr("Difficult activity cannot be computed - please report possible bug"); s+="\n"; myMutex.unlock(); //show the message in a dialog QDialog dialog(this); dialog.setWindowTitle(TimetableGenerateForm::tr("Generation stopped (highest stage)", "The title of a dialog, meaning that the generation of the timetable was stopped " "and highest stage timetable written.")); QVBoxLayout* vl=new QVBoxLayout(&dialog); QPlainTextEdit* te=new QPlainTextEdit(); te->setPlainText(s); te->setReadOnly(true); QPushButton* pb=new QPushButton(TimetableGenerateForm::tr("OK")); QHBoxLayout* hl=new QHBoxLayout(0); hl->addStretch(1); hl->addWidget(pb); vl->addWidget(te); vl->addLayout(hl); connect(pb, SIGNAL(clicked()), &dialog, SLOT(close())); dialog.resize(700,500); centerWidgetOnScreen(&dialog); restoreFETDialogGeometry(&dialog, settingsName); setParentAndOtherThings(&dialog, this); dialog.exec(); saveFETDialogGeometry(&dialog, settingsName); startPushButton->setEnabled(true); stopPushButton->setDisabled(true); stopHighestPushButton->setDisabled(true); closePushButton->setEnabled(true); writeResultsPushButton->setDisabled(true); writeHighestStagePushButton->setDisabled(true); seeImpossiblePushButton->setDisabled(true); }
void TimetableGenerateForm::impossibleToSolve() { if(!simulation_running){ return; } simulation_running=false; myMutex.lock(); gen.abortOptimization=true; myMutex.unlock(); myMutex.lock(); Solution& c=gen.c; //needed to find the conflicts strings QString tmp; c.fitness(gt.rules, &tmp); TimetableExport::getStudentsTimetable(c); TimetableExport::getTeachersTimetable(c); TimetableExport::getRoomsTimetable(c); //update the string representing the conflicts conflictsStringTitle=TimetableGenerateForm::tr("Conflicts", "Title of dialog"); conflictsString=""; conflictsString+=TimetableGenerateForm::tr("Total conflicts:"); conflictsString+=" "; conflictsString+=CustomFETString::number(c.conflictsTotal); conflictsString+="\n"; conflictsString+=TimetableGenerateForm::tr("Conflicts listing (in decreasing order):"); conflictsString+="\n"; foreach(QString t, c.conflictsDescriptionList) conflictsString+=t+"\n"; TimetableExport::writeSimulationResults(this); QString s=TimetableGenerateForm::tr("Simulation impossible! Maybe you can consider lowering the constraints."); s+=" "; QString kk; kk=FILE_SEP; if(INPUT_FILENAME_XML=="") kk.append("unnamed"); else{ kk.append(INPUT_FILENAME_XML.right(INPUT_FILENAME_XML.length()-INPUT_FILENAME_XML.lastIndexOf(FILE_SEP)-1)); if(kk.right(4)==".fet") kk=kk.left(kk.length()-4); } kk.append("-single"); s+=TimetableGenerateForm::tr("The partial results were saved in the directory %1") .arg(QDir::toNativeSeparators(OUTPUT_DIR+FILE_SEP+"timetables"+kk)); s+="\n\n"; s+=TimetableGenerateForm::tr("Additional information relating impossible to schedule activities:"); s+="\n\n"; s+=TimetableGenerateForm::tr("Please check the constraints related to the " "activity below, which might be impossible to schedule:"); s+="\n\n"; for(int i=0; i<gen.nDifficultActivities; i++){ int ai=gen.difficultActivities[i]; s+=TimetableGenerateForm::tr("No: %1").arg(i+1); s+=", "; s+=TimetableGenerateForm::tr("Id: %1 (%2)", "%1 is id of activity, %2 is detailed description of activity") .arg(gt.rules.internalActivitiesList[ai].id) .arg(getActivityDetailedDescription(gt.rules, gt.rules.internalActivitiesList[ai].id)); s+="\n"; } myMutex.unlock(); //show the message in a dialog QDialog dialog(this); dialog.setWindowTitle(TimetableGenerateForm::tr("Generation impossible", "The title of a dialog, meaning that the generation of the timetable is impossible.")); QVBoxLayout* vl=new QVBoxLayout(&dialog); QPlainTextEdit* te=new QPlainTextEdit(); te->setPlainText(s); te->setReadOnly(true); QPushButton* pb=new QPushButton(TimetableGenerateForm::tr("OK")); QHBoxLayout* hl=new QHBoxLayout(0); hl->addStretch(1); hl->addWidget(pb); vl->addWidget(te); vl->addLayout(hl); connect(pb, SIGNAL(clicked()), &dialog, SLOT(close())); dialog.resize(700,500); centerWidgetOnScreen(&dialog); restoreFETDialogGeometry(&dialog, settingsName); setParentAndOtherThings(&dialog, this); dialog.exec(); saveFETDialogGeometry(&dialog, settingsName); startPushButton->setEnabled(true); stopPushButton->setDisabled(true); stopHighestPushButton->setDisabled(true); closePushButton->setEnabled(true); writeResultsPushButton->setDisabled(true); writeHighestStagePushButton->setDisabled(true); seeImpossiblePushButton->setDisabled(true); }
void AddActivityForm::addActivity() { double weight; QString tmp=percentageLineEdit->text(); weight_sscanf(tmp, "%lf", &weight); if(percentageLineEdit->isEnabled() && (weight<0.0 || weight>100.0)){ QMessageBox::warning(this, tr("FET information"), tr("Invalid weight (percentage) for added constraint min days between activities")); return; } //teachers QStringList teachers_names; if(selectedTeachersListWidget->count()<=0){ int t=QMessageBox::question(this, tr("FET question"), tr("Do you really want to add an activity without teacher(s)?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); if(t==QMessageBox::No) return; } else{ for(int i=0; i<selectedTeachersListWidget->count(); i++){ assert(gt.rules.searchTeacher(selectedTeachersListWidget->item(i)->text())>=0); teachers_names.append(selectedTeachersListWidget->item(i)->text()); } } //subject QString subject_name=subjectsComboBox->currentText(); int subject_index=gt.rules.searchSubject(subject_name); if(subject_index<0){ QMessageBox::warning(this, tr("FET warning"), tr("Invalid subject")); return; } QStringList activity_tags_names; for(int i=0; i<selectedActivityTagsListWidget->count(); i++){ assert(gt.rules.searchActivityTag(selectedActivityTagsListWidget->item(i)->text())>=0); activity_tags_names.append(selectedActivityTagsListWidget->item(i)->text()); } //students QStringList students_names; if(selectedStudentsListWidget->count()<=0){ int t=QMessageBox::question(this, tr("FET question"), tr("Do you really want to add an activity without student set(s)?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); if(t==QMessageBox::No) return; } else{ for(int i=0; i<selectedStudentsListWidget->count(); i++){ assert(gt.rules.searchStudentsSet(selectedStudentsListWidget->item(i)->text())!=NULL); students_names.append(selectedStudentsListWidget->item(i)->text()); } } if(splitSpinBox->value()==1){ //indivisible activity int duration=duration1SpinBox->value(); if(duration<0){ QMessageBox::warning(this, tr("FET information"), tr("Invalid duration")); return; } bool active=false; if(active1CheckBox->isChecked()) active=true; int activityid=0; //We set the id of this newly added activity = (the largest existing id + 1) for(int i=0; i<gt.rules.activitiesList.size(); i++){ Activity* act=gt.rules.activitiesList[i]; if(act->id > activityid) activityid = act->id; } activityid++; Activity a(gt.rules, activityid, 0, teachers_names, subject_name, activity_tags_names, students_names, duration, duration, /*parity,*/ active, (nStudentsSpinBox->value()==-1), nStudentsSpinBox->value()); bool already_existing=false; for(int i=0; i<gt.rules.activitiesList.size(); i++){ Activity* act=gt.rules.activitiesList[i]; if((*act)==a) already_existing=true; } if(already_existing){ int t=QMessageBox::question(this, tr("FET question"), //tr("This activity already exists. Insert it again?"), tr("A similar activity already exists. Do you want to insert current activity?"), tr("Yes"),tr("No")); assert(t==0 || t==1 ||t==-1); if(t==1) //no pressed return; if(t==-1) //Esc pressed return; } bool tmp=gt.rules.addSimpleActivity(this, activityid, 0, teachers_names, subject_name, activity_tags_names, students_names, duration, duration, active, (nStudentsSpinBox->value()==-1), nStudentsSpinBox->value()); if(tmp) QMessageBox::information(this, tr("FET information"), tr("Activity added")); else QMessageBox::critical(this, tr("FET information"), tr("Activity NOT added - please report error")); } else{ //split activity if(minDayDistanceSpinBox->value()>0 && splitSpinBox->value()>gt.rules.nDaysPerWeek){ int t=LongTextMessageBox::largeConfirmation(this, tr("FET confirmation"), tr("Possible incorrect setting. Are you sure you want to add current activity? See details below:")+"\n\n"+ tr("You want to add a container activity split into more than the number of days per week and also add a constraint min days between activities." " This is a very bad practice from the way the algorithm of generation works (it slows down the generation and makes it harder to find a solution).")+ "\n\n"+ tr("The best way to add the activities would be:")+ "\n\n"+ tr("1. If you add 'force consecutive if same day', then couple extra activities in pairs to obtain a number of activities equal to the number of days per week" ". Example: 7 activities with duration 1 in a 5 days week, then transform into 5 activities with durations: 2,2,1,1,1 and add a single container activity with these 5 components" " (possibly raising the weight of added constraint min days between activities up to 100%)")+ "\n\n"+ tr("2. If you don't add 'force consecutive if same day', then add a larger activity splitted into a number of" " activities equal with the number of days per week and the remaining components into other larger splitted activity." " For example, suppose you need to add 7 activities with duration 1 in a 5 days week. Add 2 larger container activities," " first one splitted into 5 activities with duration 1 and second one splitted into 2 activities with duration 1" " (possibly raising the weight of added constraints min days between activities for each of the 2 containers up to 100%)")+ "\n\n"+ tr("Do you want to add current activities as they are now (not recommended) or cancel and edit them as instructed?") , tr("Yes"), tr("No"), QString(), 0, 1); if(t==1) return; } int totalduration; int durations[MAX_SPLIT_OF_AN_ACTIVITY]; bool active[MAX_SPLIT_OF_AN_ACTIVITY]; int nsplit=splitSpinBox->value(); totalduration=0; for(int i=0; i<nsplit; i++){ durations[i]=dur(i)->value(); active[i]=false; if(activ(i)->isChecked()) active[i]=true; totalduration+=durations[i]; } //the group id of this split activity and the id of the first partial activity //it is the maximum already existing id + 1 int firstactivityid=0; for(int i=0; i<gt.rules.activitiesList.size(); i++){ Activity* act=gt.rules.activitiesList[i]; if(act->id > firstactivityid) firstactivityid = act->id; } firstactivityid++; int minD=minDayDistanceSpinBox->value(); bool tmp=gt.rules.addSplitActivity(this, firstactivityid, firstactivityid, teachers_names, subject_name, activity_tags_names, students_names, nsplit, totalduration, durations, active, minD, weight, forceConsecutiveCheckBox->isChecked(), (nStudentsSpinBox->value()==-1), nStudentsSpinBox->value()); if(tmp){ if(minD>1 && weight<100.0){ SecondMinDaysDialog second(this, minD, weight); setParentAndOtherThings(&second, this); int code=second.exec(); if(code==QDialog::Accepted){ assert(second.weight>=0 && second.weight<=100.0); QList<int> acts; for(int i=0; i<nsplit; i++){ acts.append(firstactivityid+i); } TimeConstraint* c=new ConstraintMinDaysBetweenActivities(second.weight, forceConsecutiveCheckBox->isChecked(), nsplit, acts, minD-1); bool tmp=gt.rules.addTimeConstraint(c); assert(tmp); } } QMessageBox::information(this, tr("FET information"), tr("Split activity added." " Please note that FET currently cannot check for duplicates when adding split activities" ". It is advisable to check the statistics after adding all the activities")); } else QMessageBox::critical(this, tr("FET information"), tr("Split activity NOT added - error???")); } PlanningChanged::increasePlanningCommunicationSpinBox(); }
void AddActivityForm::help() { QString s; s+=tr("Abbreviations in this dialog:"); s+="\n\n"; s+=tr("'Students' (the text near the spin box), means 'Number of students (-1 for automatic)'"); s+="\n"; s+=tr("'Split' means 'Split into ... activities per week'"); s+="\n"; s+=tr("'Min days' means 'The minimum required distance in days between each pair of activities'"); s+="\n"; s+=tr("'Weight %' means 'Percentage of added constraint (min days between activities constraint). Recommended: 95.0%-100.0%'"); s+="\n"; s+=tr("'Consecutive' means 'If activities on same day, force consecutive?'"); s+="\n"; s+=tr("The 'Duration' spin box and the 'Active' check box refer to each component of current activity, you can change " "them for each component, separately, by selecting the corresponding tab in the tab widget."); s+="\n\n"; s+=tr("A first notice: " "If you use a 5 days week: " "when adding an activity split into only 2 components " "per week, the best practice is to add min days between activities to be 2. " "If you split an activity into 3 components per week - please read FAQ question Q1-5-September-2008"); s+="\n\n"; s+=tr("You can select a teacher from all the teachers with the mouse or with the keyboard tab/up/down, then " "double click it to add it to the selected teachers for current activity. " "You can then choose to remove a teacher from the selected teachers. You can highlight it " "with the mouse or with the keyboard, then double click it to remove this teacher from the selected teachers."); s+="\n\n"; s+=tr("The same procedure (double click) applies to students sets and activity tags."); s+="\n\n"; s+=tr("You can check/uncheck show years, show groups or show subgroups."); s+="\n\n"; s+=tr("If you split a larger activity into more activities per week, you have a multitude of choices:\n" "You can choose the minimum distance in days between each pair of activities." " Please note that a minimum distance of 1 means that the activities must not be in the same day, " "a minimum distance of 2 means that the activities must be separated by one day (distance from Monday" " to Wednesday for instance is 2 days), etc."); s+="\n\n"; s+=tr("If you have for instance an activity with 2 lessons per week and you want to spread them to at " "least 2 days distance, you can add a constraint min days with min days = 2 and weight 95% " "(or higher). If you want also to ensure that activities will " "be separated by at least one day, you can use this feature: " "add a constraint min days with minimum days 2 and weight 95% or lower, and after that you'll get " "the possibility to add another constraint with min 1 days and weight 95% or higher. " "It works if you first select in the dialog the min days >= 2 and click Add activities. Or you can add manually the constraints " "(difficult this way). " "Important: it is best practice to consider both constraints to have 95% weight. The combination assures that " "the resultant is 99.75% weight"); s+="\n\n"; s+=tr("Please note that the min days distance is a time constraint and you can only see/modify it in the " "time constraints dialogs, not in the modify activity dialog. Additionally, you can see the constraints " "for each activity in the details text box of each activity"); s+="\n\n"; s+=tr("If you choose a value greater or equal with 1 for min days, a time constraint min days between activities will be added automatically " "(you can see this constraint in the time constraints list or you can see this constraint in the " "detailed description of the activity). You can select a weight percentage for this constraint. " "If you select 100%, the constraint must be respected all the time. If you select 95%, there is a small chance " "that the timetable will not respect this constraint. Recommended values are 95.0%-100.0% (maybe you could try " "with 95%, then 99.75%, or even 100.0%, but the generation time might be larger). Generally, 99.75% might be a good value. " "Note: if you put a value less than 100% and the constraint is too tough, FET is able to find that this constraint " "is impossible and will break it. 99.75% might be better than 95% but possibly slower. The percentage is subjective " "(if you put 95% you may get 6 soft conflicts and if you put 99.75% you may get 3 soft conflicts). " "Starting with FET-5.3.6, it is possible to change this value for all constraints in one click, in constraint min days" " between activities dialog."); s+="\n\n"; s+=tr("There is another option, if the activities are in the same day, force consecutive activities. You can select " "this option for instance if you have 5 lessons of math in 5 days, and there is no timetable which respects " "fully the days separation. Then, you can set the weight percent of the min days constraint to 95% and " "add consecutive if same day. You will have as results say 3 lessons with duration 1 and a 2 hours lesson in another day. " "Please be careful: if the activities are on the same day, even if the constraint has 0% weight, then the activities are forced to be " "consecutive."); s+="\n\n"; s+=tr("Current algorithm cannot schedule 3 activities in the same day if consecutive is checked, so " "you will get no solution in such extreme cases (for instance, if you have 3 lessons and a teacher which works only 1 day per week, " "and select 'force consecutive if same day', you will get an imposssible timetable. But these are extremely unlikely cases)."); s+="\n\n"; s+=tr("Note: You cannot add 'consecutive if same day' with min days=0. If you want this, you have to add " "min days at least 1 (and any weight percentage)."); s+="\n\n"; s+=tr("Starting with version 5.0.0, it is possible to add activities with no students or no teachers"); s+="\n\n"; s+=tr("If you select a number of min days above 1 (say this number is n), you will get the possibility " "to add a second constraint min days between activities, with min days = n-1 and a percentage of your choice. Just click " "Add activities"); //show the message in a dialog QDialog dialog(this); dialog.setWindowTitle(tr("FET - help on adding activity(ies)")); QVBoxLayout* vl=new QVBoxLayout(&dialog); QPlainTextEdit* te=new QPlainTextEdit(); te->setPlainText(s); te->setReadOnly(true); QPushButton* pb=new QPushButton(tr("OK")); QHBoxLayout* hl=new QHBoxLayout(0); hl->addStretch(1); hl->addWidget(pb); vl->addWidget(te); vl->addLayout(hl); connect(pb, SIGNAL(clicked()), &dialog, SLOT(close())); dialog.resize(700,500); centerWidgetOnScreen(&dialog); setParentAndOtherThings(&dialog, this); dialog.exec(); }