1 /***************************************************************************
2                           modifyconstraintteacherroomnotavailabletimesform.cpp  -  description
3                              -------------------
4     begin                : 2019
5     copyright            : (C) 2019 by Lalescu Liviu
6     email                : Please see https://lalescu.ro/liviu/ for details about contacting Liviu Lalescu (in particular, you can find here the e-mail address)
7  ***************************************************************************/
8 
9 /***************************************************************************
10  *                                                                         *
11  *   This program is free software: you can redistribute it and/or modify  *
12  *   it under the terms of the GNU Affero General Public License as        *
13  *   published by the Free Software Foundation, either version 3 of the    *
14  *   License, or (at your option) any later version.                       *
15  *                                                                         *
16  ***************************************************************************/
17 
18 #include <QMessageBox>
19 
20 #include "modifyconstraintteacherroomnotavailabletimesform.h"
21 #include "spaceconstraint.h"
22 
23 #include <QHeaderView>
24 #include <QTableWidget>
25 #include <QTableWidgetItem>
26 
27 #include <QBrush>
28 #include <QColor>
29 
30 #define YES		(QString("X"))
31 #define NO		(QString(" "))
32 
ModifyConstraintTeacherRoomNotAvailableTimesForm(QWidget * parent,ConstraintTeacherRoomNotAvailableTimes * ctr)33 ModifyConstraintTeacherRoomNotAvailableTimesForm::ModifyConstraintTeacherRoomNotAvailableTimesForm(QWidget* parent, ConstraintTeacherRoomNotAvailableTimes* ctr): QDialog(parent)
34 {
35 	setupUi(this);
36 
37 	okPushButton->setDefault(true);
38 
39 	connect(okPushButton, SIGNAL(clicked()), this, SLOT(ok()));
40 	connect(cancelPushButton, SIGNAL(clicked()), this, SLOT(cancel()));
41 	connect(notAllowedTimesTable, SIGNAL(itemClicked(QTableWidgetItem*)), this, SLOT(itemClicked(QTableWidgetItem*)));
42 	connect(setAllAvailablePushButton, SIGNAL(clicked()), this, SLOT(setAllAvailable()));
43 	connect(setAllNotAvailablePushButton, SIGNAL(clicked()), this, SLOT(setAllNotAvailable()));
44 
45 	centerWidgetOnScreen(this);
46 	restoreFETDialogGeometry(this);
47 
48 	QSize tmp5=roomsComboBox->minimumSizeHint();
49 	Q_UNUSED(tmp5);
50 
51 	QSize tmp6=teachersComboBox->minimumSizeHint();
52 	Q_UNUSED(tmp6);
53 
54 	this->_ctr=ctr;
55 
56 	weightLineEdit->setText(CustomFETString::number(ctr->weightPercentage));
57 
58 	updateTeachersComboBox();
59 	updateRoomsComboBox();
60 
61 	notAllowedTimesTable->setRowCount(gt.rules.nHoursPerDay);
62 	notAllowedTimesTable->setColumnCount(gt.rules.nDaysPerWeek);
63 
64 	for(int j=0; j<gt.rules.nDaysPerWeek; j++){
65 		QTableWidgetItem* item=new QTableWidgetItem(gt.rules.daysOfTheWeek[j]);
66 		notAllowedTimesTable->setHorizontalHeaderItem(j, item);
67 	}
68 	for(int i=0; i<gt.rules.nHoursPerDay; i++){
69 		QTableWidgetItem* item=new QTableWidgetItem(gt.rules.hoursOfTheDay[i]);
70 		notAllowedTimesTable->setVerticalHeaderItem(i, item);
71 	}
72 
73 	Matrix2D<bool> currentMatrix;
74 	currentMatrix.resize(gt.rules.nHoursPerDay, gt.rules.nDaysPerWeek);
75 
76 	for(int i=0; i<gt.rules.nHoursPerDay; i++)
77 		for(int j=0; j<gt.rules.nDaysPerWeek; j++)
78 			currentMatrix[i][j]=false;
79 	assert(ctr->days.count()==ctr->hours.count());
80 	for(int k=0; k<ctr->days.count(); k++){
81 		if(ctr->hours.at(k)==-1 || ctr->days.at(k)==-1)
82 			assert(0);
83 		int i=ctr->hours.at(k);
84 		int j=ctr->days.at(k);
85 		if(i>=0 && i<gt.rules.nHoursPerDay && j>=0 && j<gt.rules.nDaysPerWeek)
86 			currentMatrix[i][j]=true;
87 	}
88 
89 	for(int i=0; i<gt.rules.nHoursPerDay; i++)
90 		for(int j=0; j<gt.rules.nDaysPerWeek; j++){
91 			QTableWidgetItem* item= new QTableWidgetItem();
92 			item->setTextAlignment(Qt::AlignCenter);
93 			item->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled);
94 			if(SHOW_TOOLTIPS_FOR_CONSTRAINTS_WITH_TABLES)
95 				item->setToolTip(gt.rules.daysOfTheWeek[j]+QString("\n")+gt.rules.hoursOfTheDay[i]);
96 			notAllowedTimesTable->setItem(i, j, item);
97 
98 			if(!currentMatrix[i][j])
99 				item->setText(NO);
100 			else
101 				item->setText(YES);
102 
103 			colorItem(item);
104 		}
105 
106 	notAllowedTimesTable->resizeRowsToContents();
107 
108 	connect(notAllowedTimesTable->horizontalHeader(), SIGNAL(sectionClicked(int)), this, SLOT(horizontalHeaderClicked(int)));
109 	connect(notAllowedTimesTable->verticalHeader(), SIGNAL(sectionClicked(int)), this, SLOT(verticalHeaderClicked(int)));
110 
111 	notAllowedTimesTable->setSelectionMode(QAbstractItemView::NoSelection);
112 
113 	setStretchAvailabilityTableNicely(notAllowedTimesTable);
114 }
115 
~ModifyConstraintTeacherRoomNotAvailableTimesForm()116 ModifyConstraintTeacherRoomNotAvailableTimesForm::~ModifyConstraintTeacherRoomNotAvailableTimesForm()
117 {
118 	saveFETDialogGeometry(this);
119 }
120 
colorItem(QTableWidgetItem * item)121 void ModifyConstraintTeacherRoomNotAvailableTimesForm::colorItem(QTableWidgetItem* item)
122 {
123 	if(USE_GUI_COLORS){
124 		if(item->text()==NO)
125 			item->setBackground(QBrush(Qt::darkGreen));
126 		else
127 			item->setBackground(QBrush(Qt::darkRed));
128 		item->setForeground(QBrush(Qt::lightGray));
129 	}
130 }
131 
horizontalHeaderClicked(int col)132 void ModifyConstraintTeacherRoomNotAvailableTimesForm::horizontalHeaderClicked(int col)
133 {
134 	if(col>=0 && col<gt.rules.nDaysPerWeek){
135 		QString s=notAllowedTimesTable->item(0, col)->text();
136 		if(s==YES)
137 			s=NO;
138 		else{
139 			assert(s==NO);
140 			s=YES;
141 		}
142 
143 		for(int row=0; row<gt.rules.nHoursPerDay; row++){
144 			notAllowedTimesTable->item(row, col)->setText(s);
145 			colorItem(notAllowedTimesTable->item(row,col));
146 		}
147 	}
148 }
149 
verticalHeaderClicked(int row)150 void ModifyConstraintTeacherRoomNotAvailableTimesForm::verticalHeaderClicked(int row)
151 {
152 	if(row>=0 && row<gt.rules.nHoursPerDay){
153 		QString s=notAllowedTimesTable->item(row, 0)->text();
154 		if(s==YES)
155 			s=NO;
156 		else{
157 			assert(s==NO);
158 			s=YES;
159 		}
160 
161 		for(int col=0; col<gt.rules.nDaysPerWeek; col++){
162 			notAllowedTimesTable->item(row, col)->setText(s);
163 			colorItem(notAllowedTimesTable->item(row,col));
164 		}
165 	}
166 }
167 
setAllAvailable()168 void ModifyConstraintTeacherRoomNotAvailableTimesForm::setAllAvailable()
169 {
170 	for(int i=0; i<gt.rules.nHoursPerDay; i++)
171 		for(int j=0; j<gt.rules.nDaysPerWeek; j++){
172 			notAllowedTimesTable->item(i, j)->setText(NO);
173 			colorItem(notAllowedTimesTable->item(i,j));
174 		}
175 }
176 
setAllNotAvailable()177 void ModifyConstraintTeacherRoomNotAvailableTimesForm::setAllNotAvailable()
178 {
179 	for(int i=0; i<gt.rules.nHoursPerDay; i++)
180 		for(int j=0; j<gt.rules.nDaysPerWeek; j++){
181 			notAllowedTimesTable->item(i, j)->setText(YES);
182 			colorItem(notAllowedTimesTable->item(i,j));
183 		}
184 }
185 
updateTeachersComboBox()186 void ModifyConstraintTeacherRoomNotAvailableTimesForm::updateTeachersComboBox()
187 {
188 	int i=0, j=-1;
189 	teachersComboBox->clear();
190 	for(int k=0; k<gt.rules.teachersList.size(); k++){
191 		Teacher* teacher=gt.rules.teachersList[k];
192 		teachersComboBox->addItem(teacher->name);
193 		if(teacher->name==this->_ctr->teacherName)
194 			j=i;
195 		i++;
196 	}
197 	assert(j>=0);
198 	teachersComboBox->setCurrentIndex(j);
199 }
200 
updateRoomsComboBox()201 void ModifyConstraintTeacherRoomNotAvailableTimesForm::updateRoomsComboBox()
202 {
203 	int i=0, j=-1;
204 	roomsComboBox->clear();
205 	for(int k=0; k<gt.rules.roomsList.size(); k++){
206 		Room* room=gt.rules.roomsList[k];
207 		//roomsComboBox->addItem(room->getDescription());
208 		roomsComboBox->addItem(room->name);
209 		if(room->name==this->_ctr->room)
210 			j=i;
211 		i++;
212 	}
213 	assert(j>=0);
214 	roomsComboBox->setCurrentIndex(j);
215 }
216 
itemClicked(QTableWidgetItem * item)217 void ModifyConstraintTeacherRoomNotAvailableTimesForm::itemClicked(QTableWidgetItem* item)
218 {
219 	QString s=item->text();
220 	if(s==YES)
221 		s=NO;
222 	else{
223 		assert(s==NO);
224 		s=YES;
225 	}
226 	item->setText(s);
227 	colorItem(item);
228 }
229 
cancel()230 void ModifyConstraintTeacherRoomNotAvailableTimesForm::cancel()
231 {
232 	this->close();
233 }
234 
ok()235 void ModifyConstraintTeacherRoomNotAvailableTimesForm::ok()
236 {
237 	double weight;
238 	QString tmp=weightLineEdit->text();
239 	weight_sscanf(tmp, "%lf", &weight);
240 	if(weight<0.0 || weight>100){
241 		QMessageBox::warning(this, tr("FET information"),
242 			tr("Invalid weight"));
243 		return;
244 	}
245 
246 	int j=teachersComboBox->currentIndex();
247 	if(j<0 || teachersComboBox->count()<=0){
248 		QMessageBox::warning(this, tr("FET information"),
249 			tr("Invalid teacher"));
250 		return;
251 	}
252 
253 	Teacher* teacher=gt.rules.teachersList.at(j);
254 
255 	int i=roomsComboBox->currentIndex();
256 	if(i<0 || roomsComboBox->count()<=0){
257 		QMessageBox::warning(this, tr("FET information"),
258 			tr("Invalid room"));
259 		return;
260 	}
261 
262 	Room* room=gt.rules.roomsList.at(i);
263 
264 	this->_ctr->weightPercentage=weight;
265 	this->_ctr->teacherName=teacher->name;
266 	this->_ctr->room=room->name;
267 
268 	QList<int> days;
269 	QList<int> hours;
270 	for(int j=0; j<gt.rules.nDaysPerWeek; j++)
271 		for(int i=0; i<gt.rules.nHoursPerDay; i++)
272 			if(notAllowedTimesTable->item(i, j)->text()==YES){
273 				days.append(j);
274 				hours.append(i);
275 			}
276 
277 	this->_ctr->days=days;
278 	this->_ctr->hours=hours;
279 
280 	gt.rules.internalStructureComputed=false;
281 	setRulesModifiedAndOtherThings(&gt.rules);
282 
283 	this->close();
284 }
285