1 /***************************************************************************
2 addconstraintactivitypreferredroomform.cpp - description
3 -------------------
4 begin : 7 Feb 2005
5 copyright : (C) 2005 by Liviu Lalescu
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 "longtextmessagebox.h"
21
22 #include "addconstraintactivitypreferredroomform.h"
23 #include "spaceconstraint.h"
24
25 #include <QSet>
26 #include "lockunlock.h"
27
AddConstraintActivityPreferredRoomForm(QWidget * parent)28 AddConstraintActivityPreferredRoomForm::AddConstraintActivityPreferredRoomForm(QWidget* parent): QDialog(parent)
29 {
30 setupUi(this);
31
32 addConstraintPushButton->setDefault(true);
33
34 connect(closePushButton, SIGNAL(clicked()), this, SLOT(close()));
35 connect(helpPushButton, SIGNAL(clicked()), this, SLOT(help()));
36 connect(addConstraintPushButton, SIGNAL(clicked()), this, SLOT(addConstraint()));
37
38 connect(selectedRealRoomsListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(removeRealRoom()));
39 connect(clearPushButton, SIGNAL(clicked()), this, SLOT(clearRealRooms()));
40 connect(allRealRoomsListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(addRealRoom()));
41
42 centerWidgetOnScreen(this);
43 restoreFETDialogGeometry(this);
44
45 QSize tmp1=teachersComboBox->minimumSizeHint();
46 Q_UNUSED(tmp1);
47 QSize tmp2=studentsComboBox->minimumSizeHint();
48 Q_UNUSED(tmp2);
49 QSize tmp3=subjectsComboBox->minimumSizeHint();
50 Q_UNUSED(tmp3);
51 QSize tmp4=activityTagsComboBox->minimumSizeHint();
52 Q_UNUSED(tmp4);
53
54 QSize tmp5=roomsComboBox->minimumSizeHint();
55 Q_UNUSED(tmp5);
56 QSize tmp6=activitiesComboBox->minimumSizeHint();
57 Q_UNUSED(tmp6);
58
59 activitiesComboBox->setMaximumWidth(maxRecommendedWidth(this));
60
61 teachersComboBox->addItem("");
62 for(int i=0; i<gt.rules.teachersList.size(); i++){
63 Teacher* tch=gt.rules.teachersList[i];
64 teachersComboBox->addItem(tch->name);
65 }
66 teachersComboBox->setCurrentIndex(0);
67
68 subjectsComboBox->addItem("");
69 for(int i=0; i<gt.rules.subjectsList.size(); i++){
70 Subject* sb=gt.rules.subjectsList[i];
71 subjectsComboBox->addItem(sb->name);
72 }
73 subjectsComboBox->setCurrentIndex(0);
74
75 activityTagsComboBox->addItem("");
76 for(int i=0; i<gt.rules.activityTagsList.size(); i++){
77 ActivityTag* st=gt.rules.activityTagsList[i];
78 activityTagsComboBox->addItem(st->name);
79 }
80 activityTagsComboBox->setCurrentIndex(0);
81
82 populateStudentsComboBox(studentsComboBox, QString(""), true);
83 studentsComboBox->setCurrentIndex(0);
84
85 filterChanged();
86 updateRoomsComboBox();
87
88 allRealRoomsListWidget->clear();
89 for(Room* rm : qAsConst(gt.rules.roomsList))
90 if(rm->isVirtual==false)
91 allRealRoomsListWidget->addItem(rm->name);
92 allRealRoomsListWidget->setCurrentRow(0);
93
94 connect(teachersComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(filterChanged()));
95 connect(studentsComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(filterChanged()));
96 connect(subjectsComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(filterChanged()));
97 connect(activityTagsComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(filterChanged()));
98 }
99
~AddConstraintActivityPreferredRoomForm()100 AddConstraintActivityPreferredRoomForm::~AddConstraintActivityPreferredRoomForm()
101 {
102 saveFETDialogGeometry(this);
103 }
104
filterOk(Activity * act)105 bool AddConstraintActivityPreferredRoomForm::filterOk(Activity* act)
106 {
107 QString tn=teachersComboBox->currentText();
108 QString stn=studentsComboBox->currentText();
109 QString sbn=subjectsComboBox->currentText();
110 QString atn=activityTagsComboBox->currentText();
111 int ok=true;
112
113 //teacher
114 if(tn!=""){
115 bool ok2=false;
116 for(QStringList::const_iterator it=act->teachersNames.constBegin(); it!=act->teachersNames.constEnd(); it++)
117 if(*it == tn){
118 ok2=true;
119 break;
120 }
121 if(!ok2)
122 ok=false;
123 }
124
125 //subject
126 if(sbn!="" && sbn!=act->subjectName)
127 ok=false;
128
129 //activity tag
130 if(atn!="" && !act->activityTagsNames.contains(atn))
131 ok=false;
132
133 //students
134 if(stn!=""){
135 bool ok2=false;
136 for(QStringList::const_iterator it=act->studentsNames.constBegin(); it!=act->studentsNames.constEnd(); it++)
137 if(*it == stn){
138 ok2=true;
139 break;
140 }
141 if(!ok2)
142 ok=false;
143 }
144
145 return ok;
146 }
147
filterChanged()148 void AddConstraintActivityPreferredRoomForm::filterChanged(){
149 activitiesComboBox->clear();
150 activitiesList.clear();
151
152 for(int i=0; i<gt.rules.activitiesList.size(); i++){
153 Activity* act=gt.rules.activitiesList[i];
154
155 if(filterOk(act)){
156 activitiesComboBox->addItem(act->getDescription(gt.rules));
157 this->activitiesList.append(act->id);
158 }
159 }
160 }
161
updateRoomsComboBox()162 void AddConstraintActivityPreferredRoomForm::updateRoomsComboBox()
163 {
164 roomsComboBox->clear();
165 for(int i=0; i<gt.rules.roomsList.size(); i++){
166 Room* rm=gt.rules.roomsList[i];
167 roomsComboBox->addItem(rm->name);
168 }
169 }
170
removeRealRoom()171 void AddConstraintActivityPreferredRoomForm::removeRealRoom()
172 {
173 int ind=selectedRealRoomsListWidget->currentRow();
174 if(ind<0 || ind>=selectedRealRoomsListWidget->count()){
175 QMessageBox::information(this, tr("FET information"), tr("Invalid selected real room."));
176 return;
177 }
178
179 QListWidgetItem* item=selectedRealRoomsListWidget->takeItem(ind);
180 delete item;
181
182 if(ind>=selectedRealRoomsListWidget->count())
183 ind=selectedRealRoomsListWidget->count()-1;
184 selectedRealRoomsListWidget->setCurrentRow(ind);
185 }
186
clearRealRooms()187 void AddConstraintActivityPreferredRoomForm::clearRealRooms()
188 {
189 selectedRealRoomsListWidget->clear();
190 }
191
addRealRoom()192 void AddConstraintActivityPreferredRoomForm::addRealRoom()
193 {
194 int ind=allRealRoomsListWidget->currentRow();
195 if(ind<0 || ind>=allRealRoomsListWidget->count()){
196 QMessageBox::information(this, tr("FET information"), tr("Invalid selected real room."));
197 return;
198 }
199
200 bool exists=false;
201 for(int i=0; i<selectedRealRoomsListWidget->count(); i++)
202 if(selectedRealRoomsListWidget->item(i)->text()==allRealRoomsListWidget->item(ind)->text()){
203 exists=true;
204 break;
205 }
206
207 if(!exists){
208 selectedRealRoomsListWidget->addItem(allRealRoomsListWidget->item(ind)->text());
209 selectedRealRoomsListWidget->setCurrentRow(selectedRealRoomsListWidget->count()-1);
210 }
211 }
212
addConstraint()213 void AddConstraintActivityPreferredRoomForm::addConstraint()
214 {
215 SpaceConstraint *ctr=nullptr;
216
217 double weight;
218 QString tmp=weightLineEdit->text();
219 weight_sscanf(tmp, "%lf", &weight);
220 if(weight<0.0 || weight>100){
221 QMessageBox::warning(this, tr("FET information"),
222 tr("Invalid weight (percentage)"));
223 return;
224 }
225
226 int id;
227 int tmp2=activitiesComboBox->currentIndex();
228 //assert(tmp2<gt.rules.activitiesList.size());
229 //assert(tmp2<activitiesList.size());
230 if(tmp2<0 || tmp2>=gt.rules.activitiesList.size() || tmp2>=activitiesList.size()){
231 QMessageBox::warning(this, tr("FET information"),
232 tr("Invalid activity"));
233 return;
234 }
235 else
236 id=activitiesList.at(tmp2);
237
238 /*int i=activitiesComboBox->currentIndex();
239 if(i<0 || activitiesComboBox->count()<=0){
240 QMessageBox::warning(this, tr("FET information"),
241 tr("Invalid activity"));
242 return;
243 }
244 Activity* act=gt.rules.activitiesList.at(i);*/
245
246 int i=roomsComboBox->currentIndex();
247 if(i<0 || roomsComboBox->count()<=0){
248 QMessageBox::warning(this, tr("FET information"),
249 tr("Invalid room"));
250 return;
251 }
252 QString room=roomsComboBox->currentText();
253
254 int ri=gt.rules.searchRoom(room);
255 assert(ri>=0);
256 Room* rm=gt.rules.roomsList.at(ri);
257
258 if(rm->isVirtual==false){
259 if(selectedRealRoomsListWidget->count()>0){
260 QMessageBox::warning(this, tr("FET information"), tr("The preferred room of the activity is a real room, not a virtual one."
261 " This implies that the selected real rooms list should be empty."));
262 return;
263 }
264 }
265 else{
266 if(selectedRealRoomsListWidget->count()>0 && weight<100.0){
267 QMessageBox::warning(this, tr("FET information"), tr("If the preferred room is virtual and the list of real rooms is not empty,"
268 " the weight percentage must be exactly 100%."));
269 return;
270 }
271
272 if(selectedRealRoomsListWidget->count()>0 && rm->realRoomsSetsList.count()!=selectedRealRoomsListWidget->count()){
273 QMessageBox::warning(this, tr("FET information"), tr("The preferred room of the activity is a virtual room."
274 " This implies that the number of selected real rooms in the list should either be zero or equal to the"
275 " number of sets of real rooms of the preferred virtual room, which is %1.").arg(rm->realRoomsSetsList.count()));
276 return;
277 }
278
279 QSet<QString> rrs;
280 for(const QStringList& tl : qAsConst(rm->realRoomsSetsList))
281 for(const QString& s : qAsConst(tl))
282 if(!rrs.contains(s))
283 rrs.insert(s);
284
285 QStringList incorrectList;
286 for(int i=0; i<selectedRealRoomsListWidget->count(); i++){
287 bool found=false;
288 QString rrn=selectedRealRoomsListWidget->item(i)->text();
289 if(rrs.contains(rrn))
290 found=true;
291
292 if(!found)
293 incorrectList.append(rrn);
294 }
295 if(!incorrectList.isEmpty()){
296 switch(LongTextMessageBox::confirmation(this, tr("FET information"), tr("The selected real rooms: %1 are not found in the sets of sets of real rooms of the"
297 " selected preferred virtual room. This is probably wrong. Are you sure you want to add this constraint?").arg(incorrectList.join(", ")),
298 tr("Yes"), tr("No"), 0, 0, 1)){
299 case 0:
300 break;
301 case 1:
302 return;
303 }
304 }
305 }
306
307 QStringList lst;
308 for(int i=0; i<selectedRealRoomsListWidget->count(); i++)
309 lst.append(selectedRealRoomsListWidget->item(i)->text());
310
311 ctr=new ConstraintActivityPreferredRoom(weight, id, room, lst, permLockedCheckBox->isChecked());
312
313 bool tmp3=gt.rules.addSpaceConstraint(ctr);
314 if(tmp3){
315 QString s=tr("Constraint added:");
316 s+="\n\n";
317 s+=ctr->getDetailedDescription(gt.rules);
318 LongTextMessageBox::information(this, tr("FET information"), s);
319
320 /*if(permLockedCheckBox->isChecked()) wrong, must take care of weight==100.0
321 idsOfPermanentlyLockedSpace.insert(id);
322 else
323 idsOfLockedSpace.insert(id);*/
324 LockUnlock::computeLockedUnlockedActivitiesOnlySpace(); //safer
325 LockUnlock::increaseCommunicationSpinBox();
326 }
327 else{
328 QMessageBox::warning(this, tr("FET information"),
329 tr("Constraint NOT added - must be a duplicate"));
330 delete ctr;
331 }
332 }
333
help()334 void AddConstraintActivityPreferredRoomForm::help()
335 {
336 QString s;
337
338 s+=tr("A room can be real (the simplest and the most used scenario) or virtual. You can read more about this in the rooms dialog, by clicking the Help button there.");
339 s+="\n\n";
340 s+=tr("If the preferred room selected in the combo box is real, the list of selected real rooms must remain empty.");
341 s+="\n\n";
342 s+=tr("If the preferred room selected in the combo box is virtual, you can select also the list of real rooms to be allocated to the "
343 "selected activity (if the preferred room selected in the combo box is virtual and the list of selected real rooms is not empty, the "
344 "weight of the constraint must be 100.0%).");
345
346 LongTextMessageBox::largeInformation(this, tr("FET help"), s);
347 }
348