1 /***************************************************************************
2 modifyconstraintteachernotavailabletimesform.cpp - description
3 -------------------
4 begin : Feb 10, 2005
5 copyright : (C) 2005 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 <Qt>
19
20 #include <QMessageBox>
21
22 #include "modifyconstraintteachernotavailabletimesform.h"
23 #include "timeconstraint.h"
24
25 #include <QHeaderView>
26 #include <QTableWidget>
27 #include <QTableWidgetItem>
28
29 #include <QBrush>
30 #include <QColor>
31
32 #define YES (QString("X"))
33 #define NO (QString(" "))
34
ModifyConstraintTeacherNotAvailableTimesForm(QWidget * parent,ConstraintTeacherNotAvailableTimes * ctr)35 ModifyConstraintTeacherNotAvailableTimesForm::ModifyConstraintTeacherNotAvailableTimesForm(QWidget* parent, ConstraintTeacherNotAvailableTimes* ctr): QDialog(parent)
36 {
37 setupUi(this);
38
39 okPushButton->setDefault(true);
40
41 connect(okPushButton, SIGNAL(clicked()), this, SLOT(ok()));
42 connect(cancelPushButton, SIGNAL(clicked()), this, SLOT(cancel()));
43 connect(notAllowedTimesTable, SIGNAL(itemClicked(QTableWidgetItem*)), this, SLOT(itemClicked(QTableWidgetItem*)));
44 connect(setAllAvailablePushButton, SIGNAL(clicked()), this, SLOT(setAllAvailable()));
45 connect(setAllNotAvailablePushButton, SIGNAL(clicked()), this, SLOT(setAllNotAvailable()));
46
47 centerWidgetOnScreen(this);
48 restoreFETDialogGeometry(this);
49
50 QSize tmp1=teachersComboBox->minimumSizeHint();
51 Q_UNUSED(tmp1);
52
53 this->_ctr=ctr;
54
55 weightLineEdit->setText(CustomFETString::number(ctr->weightPercentage));
56
57 updateTeachersComboBox();
58
59 notAllowedTimesTable->setRowCount(gt.rules.nHoursPerDay);
60 notAllowedTimesTable->setColumnCount(gt.rules.nDaysPerWeek);
61
62 for(int j=0; j<gt.rules.nDaysPerWeek; j++){
63 QTableWidgetItem* item=new QTableWidgetItem(gt.rules.daysOfTheWeek[j]);
64 notAllowedTimesTable->setHorizontalHeaderItem(j, item);
65 }
66 for(int i=0; i<gt.rules.nHoursPerDay; i++){
67 QTableWidgetItem* item=new QTableWidgetItem(gt.rules.hoursOfTheDay[i]);
68 notAllowedTimesTable->setVerticalHeaderItem(i, item);
69 }
70
71 Matrix2D<bool> currentMatrix;
72 currentMatrix.resize(gt.rules.nHoursPerDay, gt.rules.nDaysPerWeek);
73
74 for(int i=0; i<gt.rules.nHoursPerDay; i++)
75 for(int j=0; j<gt.rules.nDaysPerWeek; j++)
76 currentMatrix[i][j]=false;
77 assert(ctr->days.count()==ctr->hours.count());
78 for(int k=0; k<ctr->days.count(); k++){
79 if(ctr->hours.at(k)==-1 || ctr->days.at(k)==-1)
80 assert(0);
81 int i=ctr->hours.at(k);
82 int j=ctr->days.at(k);
83 if(i>=0 && i<gt.rules.nHoursPerDay && j>=0 && j<gt.rules.nDaysPerWeek)
84 currentMatrix[i][j]=true;
85 }
86
87 for(int i=0; i<gt.rules.nHoursPerDay; i++)
88 for(int j=0; j<gt.rules.nDaysPerWeek; j++){
89 QTableWidgetItem* item= new QTableWidgetItem();
90 item->setTextAlignment(Qt::AlignCenter);
91 item->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled);
92 if(SHOW_TOOLTIPS_FOR_CONSTRAINTS_WITH_TABLES)
93 item->setToolTip(gt.rules.daysOfTheWeek[j]+QString("\n")+gt.rules.hoursOfTheDay[i]);
94 notAllowedTimesTable->setItem(i, j, item);
95
96 if(!currentMatrix[i][j])
97 item->setText(NO);
98 else
99 item->setText(YES);
100
101 colorItem(item);
102 }
103
104 notAllowedTimesTable->resizeRowsToContents();
105
106 connect(notAllowedTimesTable->horizontalHeader(), SIGNAL(sectionClicked(int)), this, SLOT(horizontalHeaderClicked(int)));
107 connect(notAllowedTimesTable->verticalHeader(), SIGNAL(sectionClicked(int)), this, SLOT(verticalHeaderClicked(int)));
108
109 notAllowedTimesTable->setSelectionMode(QAbstractItemView::NoSelection);
110
111 setStretchAvailabilityTableNicely(notAllowedTimesTable);
112 }
113
~ModifyConstraintTeacherNotAvailableTimesForm()114 ModifyConstraintTeacherNotAvailableTimesForm::~ModifyConstraintTeacherNotAvailableTimesForm()
115 {
116 saveFETDialogGeometry(this);
117 }
118
colorItem(QTableWidgetItem * item)119 void ModifyConstraintTeacherNotAvailableTimesForm::colorItem(QTableWidgetItem* item)
120 {
121 if(USE_GUI_COLORS){
122 #if QT_VERSION >= QT_VERSION_CHECK(5,14,0)
123 if(item->text()==NO)
124 item->setBackground(QBrush(QColorConstants::DarkGreen));
125 else
126 item->setBackground(QBrush(QColorConstants::DarkRed));
127 item->setForeground(QBrush(QColorConstants::LightGray));
128 #else
129 if(item->text()==NO)
130 item->setBackground(QBrush(Qt::darkGreen));
131 else
132 item->setBackground(QBrush(Qt::darkRed));
133 item->setForeground(QBrush(Qt::lightGray));
134 #endif
135 }
136 }
137
horizontalHeaderClicked(int col)138 void ModifyConstraintTeacherNotAvailableTimesForm::horizontalHeaderClicked(int col)
139 {
140 if(col>=0 && col<gt.rules.nDaysPerWeek){
141 QString s=notAllowedTimesTable->item(0, col)->text();
142 if(s==YES)
143 s=NO;
144 else{
145 assert(s==NO);
146 s=YES;
147 }
148
149 for(int row=0; row<gt.rules.nHoursPerDay; row++){
150 notAllowedTimesTable->item(row, col)->setText(s);
151 colorItem(notAllowedTimesTable->item(row,col));
152 }
153 }
154 }
155
verticalHeaderClicked(int row)156 void ModifyConstraintTeacherNotAvailableTimesForm::verticalHeaderClicked(int row)
157 {
158 if(row>=0 && row<gt.rules.nHoursPerDay){
159 QString s=notAllowedTimesTable->item(row, 0)->text();
160 if(s==YES)
161 s=NO;
162 else{
163 assert(s==NO);
164 s=YES;
165 }
166
167 for(int col=0; col<gt.rules.nDaysPerWeek; col++){
168 notAllowedTimesTable->item(row, col)->setText(s);
169 colorItem(notAllowedTimesTable->item(row,col));
170 }
171 }
172 }
173
setAllAvailable()174 void ModifyConstraintTeacherNotAvailableTimesForm::setAllAvailable()
175 {
176 for(int i=0; i<gt.rules.nHoursPerDay; i++)
177 for(int j=0; j<gt.rules.nDaysPerWeek; j++){
178 notAllowedTimesTable->item(i, j)->setText(NO);
179 colorItem(notAllowedTimesTable->item(i,j));
180 }
181 }
182
setAllNotAvailable()183 void ModifyConstraintTeacherNotAvailableTimesForm::setAllNotAvailable()
184 {
185 for(int i=0; i<gt.rules.nHoursPerDay; i++)
186 for(int j=0; j<gt.rules.nDaysPerWeek; j++){
187 notAllowedTimesTable->item(i, j)->setText(YES);
188 colorItem(notAllowedTimesTable->item(i,j));
189 }
190 }
191
updateTeachersComboBox()192 void ModifyConstraintTeacherNotAvailableTimesForm::updateTeachersComboBox(){
193 teachersComboBox->clear();
194 int i=0, j=-1;
195 for(int k=0; k<gt.rules.teachersList.size(); k++, i++){
196 Teacher* tch=gt.rules.teachersList[k];
197 teachersComboBox->addItem(tch->name);
198 if(tch->name==this->_ctr->teacher)
199 j=i;
200 }
201 assert(j>=0);
202 teachersComboBox->setCurrentIndex(j);
203 }
204
itemClicked(QTableWidgetItem * item)205 void ModifyConstraintTeacherNotAvailableTimesForm::itemClicked(QTableWidgetItem* item)
206 {
207 QString s=item->text();
208 if(s==YES)
209 s=NO;
210 else{
211 assert(s==NO);
212 s=YES;
213 }
214 item->setText(s);
215 colorItem(item);
216 }
217
ok()218 void ModifyConstraintTeacherNotAvailableTimesForm::ok()
219 {
220 double weight;
221 QString tmp=weightLineEdit->text();
222 weight_sscanf(tmp, "%lf", &weight);
223 if(weight<100.0 || weight>100.0){
224 QMessageBox::warning(this, tr("FET information"),
225 tr("Invalid weight (percentage). It has to be 100"));
226 return;
227 }
228
229 QString teacher_name=teachersComboBox->currentText();
230 int teacher_ID=gt.rules.searchTeacher(teacher_name);
231 if(teacher_ID<0){
232 QMessageBox::warning(this, tr("FET information"),
233 tr("Invalid teacher"));
234 return;
235 }
236
237 for(TimeConstraint* c : qAsConst(gt.rules.timeConstraintsList))
238 if(c!=this->_ctr && c->type==CONSTRAINT_TEACHER_NOT_AVAILABLE_TIMES){
239 ConstraintTeacherNotAvailableTimes* cc=(ConstraintTeacherNotAvailableTimes*)c;
240 if(cc->teacher==teacher_name){
241 QMessageBox::warning(this, tr("FET information"),
242 tr("A constraint of this type exists for the same teacher - cannot proceed"));
243 return;
244 }
245 }
246
247 this->_ctr->weightPercentage=weight;
248
249 if(_ctr->teacher!=teacher_name){
250 QString oldName=_ctr->teacher;
251 QString newName=teacher_name;
252
253 QSet<ConstraintTeacherNotAvailableTimes*> cs=gt.rules.tnatHash.value(oldName, QSet<ConstraintTeacherNotAvailableTimes*>());
254 assert(cs.contains(_ctr));
255 cs.remove(_ctr);
256 gt.rules.tnatHash.insert(oldName, cs);
257
258 cs=gt.rules.tnatHash.value(newName, QSet<ConstraintTeacherNotAvailableTimes*>());
259 assert(!cs.contains(_ctr));
260 cs.insert(_ctr);
261 gt.rules.tnatHash.insert(newName, cs);
262
263 this->_ctr->teacher=teacher_name;
264 }
265
266 QList<int> days;
267 QList<int> hours;
268 for(int j=0; j<gt.rules.nDaysPerWeek; j++)
269 for(int i=0; i<gt.rules.nHoursPerDay; i++)
270 if(notAllowedTimesTable->item(i, j)->text()==YES){
271 days.append(j);
272 hours.append(i);
273 }
274
275 this->_ctr->days=days;
276 this->_ctr->hours=hours;
277
278 gt.rules.internalStructureComputed=false;
279 setRulesModifiedAndOtherThings(>.rules);
280
281 this->close();
282 }
283
cancel()284 void ModifyConstraintTeacherNotAvailableTimesForm::cancel()
285 {
286 this->close();
287 }
288