Ejemplo n.º 1
0
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);
}
Ejemplo n.º 3
0
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();
}
Ejemplo n.º 5
0
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);
}
Ejemplo n.º 7
0
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);
}
Ejemplo n.º 10
0
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);
}
Ejemplo n.º 12
0
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);
}
Ejemplo n.º 14
0
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);
}
Ejemplo n.º 16
0
void ConstraintTeacherNotAvailableTimesForm::addConstraint()
{
	AddConstraintTeacherNotAvailableTimesForm form(this);
	setParentAndOtherThings(&form, this);
	form.exec();

	filterChanged();
	
	constraintsListWidget->setCurrentRow(constraintsListWidget->count()-1);
}
Ejemplo n.º 17
0
void ConstraintActivitiesSameRoomIfConsecutiveForm::addConstraint()
{
	AddConstraintActivitiesSameRoomIfConsecutiveForm form(this);
	setParentAndOtherThings(&form, this);
	form.exec();

	filterChanged();
	
	constraintsListWidget->setCurrentRow(constraintsListWidget->count()-1);
}
Ejemplo n.º 18
0
void ConstraintTeacherHomeRoomsForm::addConstraint()
{
	AddConstraintTeacherHomeRoomsForm form(this);
	setParentAndOtherThings(&form, this);
	form.exec();

	this->refreshConstraintsListWidget();
	
	constraintsListWidget->setCurrentRow(constraintsListWidget->count()-1);
}
Ejemplo n.º 19
0
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);
}
Ejemplo n.º 22
0
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();
}
Ejemplo n.º 23
0
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(""));
}
Ejemplo n.º 24
0
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);
}
Ejemplo n.º 25
0
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();
}
Ejemplo n.º 26
0
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(""));
}
Ejemplo n.º 27
0
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);
}
Ejemplo n.º 28
0
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);
}
Ejemplo n.º 29
0
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();
}
Ejemplo n.º 30
0
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();
}