1 /***************************************************************************
2 modifyconstraintstudentssetnotavailabletimesform.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 "modifyconstraintstudentssetnotavailabletimesform.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
ModifyConstraintStudentsSetNotAvailableTimesForm(QWidget * parent,ConstraintStudentsSetNotAvailableTimes * ctr)35 ModifyConstraintStudentsSetNotAvailableTimesForm::ModifyConstraintStudentsSetNotAvailableTimesForm(QWidget* parent, ConstraintStudentsSetNotAvailableTimes* 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 tmp2=studentsComboBox->minimumSizeHint();
51 Q_UNUSED(tmp2);
52
53 this->_ctr=ctr;
54
55 weightLineEdit->setText(CustomFETString::number(ctr->weightPercentage));
56
57 updateStudentsComboBox(parent);
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
~ModifyConstraintStudentsSetNotAvailableTimesForm()114 ModifyConstraintStudentsSetNotAvailableTimesForm::~ModifyConstraintStudentsSetNotAvailableTimesForm()
115 {
116 saveFETDialogGeometry(this);
117 }
118
colorItem(QTableWidgetItem * item)119 void ModifyConstraintStudentsSetNotAvailableTimesForm::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 ModifyConstraintStudentsSetNotAvailableTimesForm::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 ModifyConstraintStudentsSetNotAvailableTimesForm::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 ModifyConstraintStudentsSetNotAvailableTimesForm::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 ModifyConstraintStudentsSetNotAvailableTimesForm::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
itemClicked(QTableWidgetItem * item)192 void ModifyConstraintStudentsSetNotAvailableTimesForm::itemClicked(QTableWidgetItem* item)
193 {
194 QString s=item->text();
195 if(s==YES)
196 s=NO;
197 else{
198 assert(s==NO);
199 s=YES;
200 }
201 item->setText(s);
202 colorItem(item);
203 }
204
updateStudentsComboBox(QWidget * parent)205 void ModifyConstraintStudentsSetNotAvailableTimesForm::updateStudentsComboBox(QWidget* parent){
206 int j=populateStudentsComboBox(studentsComboBox, this->_ctr->students);
207 if(j<0)
208 showWarningForInvisibleSubgroupConstraint(parent, this->_ctr->students);
209 else
210 assert(j>=0);
211 studentsComboBox->setCurrentIndex(j);
212 }
213
ok()214 void ModifyConstraintStudentsSetNotAvailableTimesForm::ok()
215 {
216 if(studentsComboBox->currentIndex()<0){
217 showWarningCannotModifyConstraintInvisibleSubgroupConstraint(this, this->_ctr->students);
218 return;
219 }
220
221 double weight;
222 QString tmp=weightLineEdit->text();
223 weight_sscanf(tmp, "%lf", &weight);
224 if(weight<100.0 || weight>100.0){
225 QMessageBox::warning(this, tr("FET information"),
226 tr("Invalid weight (percentage). It has to be 100"));
227 return;
228 }
229
230 QString students_name=studentsComboBox->currentText();
231 StudentsSet* s=gt.rules.searchStudentsSet(students_name);
232 if(s==nullptr){
233 QMessageBox::warning(this, tr("FET information"),
234 tr("Invalid students set"));
235 return;
236 }
237
238 for(TimeConstraint* c : qAsConst(gt.rules.timeConstraintsList))
239 if(c!=this->_ctr && c->type==CONSTRAINT_STUDENTS_SET_NOT_AVAILABLE_TIMES){
240 ConstraintStudentsSetNotAvailableTimes* cc=(ConstraintStudentsSetNotAvailableTimes*)c;
241 if(cc->students==students_name){
242 QMessageBox::warning(this, tr("FET information"),
243 tr("A constraint of this type exists for the same students set - cannot proceed"));
244 return;
245 }
246 }
247
248 this->_ctr->weightPercentage=weight;
249
250 if(_ctr->students!=students_name){
251 QString oldName=_ctr->students;
252 QString newName=students_name;
253
254 QSet<ConstraintStudentsSetNotAvailableTimes*> cs=gt.rules.ssnatHash.value(oldName, QSet<ConstraintStudentsSetNotAvailableTimes*>());
255 assert(cs.contains(_ctr));
256 cs.remove(_ctr);
257 gt.rules.ssnatHash.insert(oldName, cs);
258
259 cs=gt.rules.ssnatHash.value(newName, QSet<ConstraintStudentsSetNotAvailableTimes*>());
260 assert(!cs.contains(_ctr));
261 cs.insert(_ctr);
262 gt.rules.ssnatHash.insert(newName, cs);
263
264 this->_ctr->students=students_name;
265 }
266
267 QList<int> days;
268 QList<int> hours;
269 for(int j=0; j<gt.rules.nDaysPerWeek; j++)
270 for(int i=0; i<gt.rules.nHoursPerDay; i++)
271 if(notAllowedTimesTable->item(i, j)->text()==YES){
272 days.append(j);
273 hours.append(i);
274 }
275
276 this->_ctr->days=days;
277 this->_ctr->hours=hours;
278
279 gt.rules.internalStructureComputed=false;
280 setRulesModifiedAndOtherThings(>.rules);
281
282 this->close();
283 }
284
cancel()285 void ModifyConstraintStudentsSetNotAvailableTimesForm::cancel()
286 {
287 this->close();
288 }
289