1 /***************************************************************************
2 allspaceconstraintsform.cpp - description
3 -------------------
4 begin : Feb 13, 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 "longtextmessagebox.h"
21
22 #include "allspaceconstraintsform.h"
23
24 #include "modifyconstraintbasiccompulsoryspaceform.h"
25 #include "modifyconstraintroomnotavailabletimesform.h"
26 #include "modifyconstraintteacherroomnotavailabletimesform.h"
27 #include "modifyconstraintactivitypreferredroomform.h"
28 #include "modifyconstraintactivitypreferredroomsform.h"
29
30 #include "modifyconstraintstudentssethomeroomform.h"
31 #include "modifyconstraintstudentssethomeroomsform.h"
32
33 #include "modifyconstraintteacherhomeroomform.h"
34 #include "modifyconstraintteacherhomeroomsform.h"
35
36 #include "modifyconstraintstudentssetmaxbuildingchangesperdayform.h"
37 #include "modifyconstraintstudentsmaxbuildingchangesperdayform.h"
38 #include "modifyconstraintstudentssetmaxbuildingchangesperweekform.h"
39 #include "modifyconstraintstudentsmaxbuildingchangesperweekform.h"
40 #include "modifyconstraintstudentssetmingapsbetweenbuildingchangesform.h"
41 #include "modifyconstraintstudentsmingapsbetweenbuildingchangesform.h"
42
43 #include "modifyconstraintteachermaxbuildingchangesperdayform.h"
44 #include "modifyconstraintteachersmaxbuildingchangesperdayform.h"
45 #include "modifyconstraintteachermaxbuildingchangesperweekform.h"
46 #include "modifyconstraintteachersmaxbuildingchangesperweekform.h"
47 #include "modifyconstraintteachermingapsbetweenbuildingchangesform.h"
48 #include "modifyconstraintteachersmingapsbetweenbuildingchangesform.h"
49
50 #include "modifyconstraintstudentssetmaxroomchangesperrealdayform.h"
51 #include "modifyconstraintstudentsmaxroomchangesperrealdayform.h"
52
53 #include "modifyconstraintstudentssetmaxroomchangesperdayform.h"
54 #include "modifyconstraintstudentsmaxroomchangesperdayform.h"
55 #include "modifyconstraintstudentssetmaxroomchangesperweekform.h"
56 #include "modifyconstraintstudentsmaxroomchangesperweekform.h"
57 #include "modifyconstraintstudentssetmingapsbetweenroomchangesform.h"
58 #include "modifyconstraintstudentsmingapsbetweenroomchangesform.h"
59
60 #include "modifyconstraintteachermaxroomchangesperrealdayform.h"
61 #include "modifyconstraintteachersmaxroomchangesperrealdayform.h"
62
63 #include "modifyconstraintteachermaxroomchangesperdayform.h"
64 #include "modifyconstraintteachersmaxroomchangesperdayform.h"
65 #include "modifyconstraintteachermaxroomchangesperweekform.h"
66 #include "modifyconstraintteachersmaxroomchangesperweekform.h"
67 #include "modifyconstraintteachermingapsbetweenroomchangesform.h"
68 #include "modifyconstraintteachersmingapsbetweenroomchangesform.h"
69
70 #include "modifyconstraintsubjectpreferredroomform.h"
71 #include "modifyconstraintsubjectpreferredroomsform.h"
72 #include "modifyconstraintsubjectactivitytagpreferredroomform.h"
73 #include "modifyconstraintsubjectactivitytagpreferredroomsform.h"
74
75 #include "modifyconstraintactivitytagpreferredroomform.h"
76 #include "modifyconstraintactivitytagpreferredroomsform.h"
77
78 #include "modifyconstraintactivitiesoccupymaxdifferentroomsform.h"
79 #include "modifyconstraintactivitiessameroomifconsecutiveform.h"
80
81 #include "lockunlock.h"
82
83 #include "advancedfilterform.h"
84
85 #include <QMessageBox>
86
87 #include <QPlainTextEdit>
88
89 #if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
90 #include <QRegularExpression>
91 #include <QRegularExpressionMatch>
92 #else
93 #include <QRegExp>
94 #endif
95
96 #include <QListWidget>
97 #include <QListWidgetItem>
98 #include <QScrollBar>
99 #include <QAbstractItemView>
100
101 #include <QSplitter>
102 #include <QSettings>
103 #include <QObject>
104 #include <QMetaObject>
105
106 #include <QBrush>
107 #include <QPalette>
108
109 #include <QtAlgorithms>
110
111 #include <algorithm>
112 //using namespace std;
113
114 extern const QString COMPANY;
115 extern const QString PROGRAM;
116
117 const int DESCRIPTION=0;
118 //const int DETDESCRIPTION=1;
119
120 const int CONTAINS=0;
121 const int DOESNOTCONTAIN=1;
122 const int REGEXP=2;
123 const int NOTREGEXP=3;
124
AllSpaceConstraintsForm(QWidget * parent)125 AllSpaceConstraintsForm::AllSpaceConstraintsForm(QWidget* parent): QDialog(parent)
126 {
127 setupUi(this);
128
129 filterCheckBox->setChecked(false);
130 sortedCheckBox->setChecked(false);
131
132 currentConstraintTextEdit->setReadOnly(true);
133
134 modifyConstraintPushButton->setDefault(true);
135
136 constraintsListWidget->setSelectionMode(QAbstractItemView::SingleSelection);
137
138 connect(constraintsListWidget, SIGNAL(currentRowChanged(int)), this, SLOT(constraintChanged()));
139 connect(closePushButton, SIGNAL(clicked()), this, SLOT(close()));
140 connect(removeConstraintPushButton, SIGNAL(clicked()), this, SLOT(removeConstraint()));
141 connect(modifyConstraintPushButton, SIGNAL(clicked()), this, SLOT(modifyConstraint()));
142 connect(constraintsListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(modifyConstraint()));
143 connect(filterCheckBox, SIGNAL(toggled(bool)), this, SLOT(filter(bool)));
144
145 connect(moveSpaceConstraintUpPushButton, SIGNAL(clicked()), this, SLOT(moveSpaceConstraintUp()));
146 connect(moveSpaceConstraintDownPushButton, SIGNAL(clicked()), this, SLOT(moveSpaceConstraintDown()));
147
148 connect(sortedCheckBox, SIGNAL(toggled(bool)), this, SLOT(sortedChanged(bool)));
149 connect(activatePushButton, SIGNAL(clicked()), this, SLOT(activateConstraint()));
150 connect(deactivatePushButton, SIGNAL(clicked()), this, SLOT(deactivateConstraint()));
151 //connect(sortByCommentsPushButton, SIGNAL(clicked()), this, SLOT(sortConstraintsByComments()));
152 connect(commentsPushButton, SIGNAL(clicked()), this, SLOT(constraintComments()));
153
154 centerWidgetOnScreen(this);
155 restoreFETDialogGeometry(this);
156 //restore splitter state
157 QSettings settings(COMPANY, PROGRAM);
158 if(settings.contains(this->metaObject()->className()+QString("/splitter-state")))
159 splitter->restoreState(settings.value(this->metaObject()->className()+QString("/splitter-state")).toByteArray());
160
161 QString settingsName="AllSpaceConstraintsAdvancedFilterForm";
162
163 all=settings.value(settingsName+"/all-conditions", "true").toBool();
164
165 descrDetDescr.clear();
166 int n=settings.value(settingsName+"/number-of-descriptions", "1").toInt();
167 for(int i=0; i<n; i++)
168 descrDetDescr.append(settings.value(settingsName+"/description/"+CustomFETString::number(i+1), CustomFETString::number(DESCRIPTION)).toInt());
169
170 contains.clear();
171 n=settings.value(settingsName+"/number-of-contains", "1").toInt();
172 for(int i=0; i<n; i++)
173 contains.append(settings.value(settingsName+"/contains/"+CustomFETString::number(i+1), CustomFETString::number(CONTAINS)).toInt());
174
175 text.clear();
176 n=settings.value(settingsName+"/number-of-texts", "1").toInt();
177 for(int i=0; i<n; i++)
178 text.append(settings.value(settingsName+"/text/"+CustomFETString::number(i+1), QString("")).toString());
179
180 caseSensitive=settings.value(settingsName+"/case-sensitive", "false").toBool();
181
182 useFilter=false;
183
184 assert(filterCheckBox->isChecked()==false);
185 assert(sortedCheckBox->isChecked()==false);
186
187 filterChanged();
188 }
189
~AllSpaceConstraintsForm()190 AllSpaceConstraintsForm::~AllSpaceConstraintsForm()
191 {
192 saveFETDialogGeometry(this);
193 //save splitter state
194 QSettings settings(COMPANY, PROGRAM);
195 settings.setValue(this->metaObject()->className()+QString("/splitter-state"), splitter->saveState());
196
197 QString settingsName="AllSpaceConstraintsAdvancedFilterForm";
198
199 settings.setValue(settingsName+"/all-conditions", all);
200
201 settings.setValue(settingsName+"/number-of-descriptions", descrDetDescr.count());
202 settings.remove(settingsName+"/description");
203 for(int i=0; i<descrDetDescr.count(); i++)
204 settings.setValue(settingsName+"/description/"+CustomFETString::number(i+1), descrDetDescr.at(i));
205
206 settings.setValue(settingsName+"/number-of-contains", contains.count());
207 settings.remove(settingsName+"/contains");
208 for(int i=0; i<contains.count(); i++)
209 settings.setValue(settingsName+"/contains/"+CustomFETString::number(i+1), contains.at(i));
210
211 settings.setValue(settingsName+"/number-of-texts", text.count());
212 settings.remove(settingsName+"/text");
213 for(int i=0; i<text.count(); i++)
214 settings.setValue(settingsName+"/text/"+CustomFETString::number(i+1), text.at(i));
215
216 settings.setValue(settingsName+"/case-sensitive", caseSensitive);
217 }
218
filterOk(SpaceConstraint * ctr)219 bool AllSpaceConstraintsForm::filterOk(SpaceConstraint* ctr)
220 {
221 if(!useFilter)
222 return true;
223
224 assert(descrDetDescr.count()==contains.count());
225 assert(contains.count()==text.count());
226
227 Qt::CaseSensitivity csens=Qt::CaseSensitive;
228 if(!caseSensitive)
229 csens=Qt::CaseInsensitive;
230
231 QList<bool> okPartial;
232
233 for(int i=0; i<descrDetDescr.count(); i++){
234 QString s;
235 if(descrDetDescr.at(i)==DESCRIPTION)
236 s=ctr->getDescription(gt.rules);
237 else
238 s=ctr->getDetailedDescription(gt.rules);
239
240 QString t=text.at(i);
241 if(contains.at(i)==CONTAINS){
242 okPartial.append(s.contains(t, csens));
243 }
244 else if(contains.at(i)==DOESNOTCONTAIN){
245 okPartial.append(!(s.contains(t, csens)));
246 }
247 #if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
248 else if(contains.at(i)==REGEXP){
249 QRegularExpression regExp(t);
250 if(!caseSensitive)
251 regExp.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
252 okPartial.append((regExp.match(s)).hasMatch());
253 }
254 else if(contains.at(i)==NOTREGEXP){
255 QRegularExpression regExp(t);
256 if(!caseSensitive)
257 regExp.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
258 okPartial.append(!(regExp.match(s)).hasMatch());
259 }
260 #else
261 else if(contains.at(i)==REGEXP){
262 QRegExp regExp(t);
263 regExp.setCaseSensitivity(csens);
264 okPartial.append(regExp.indexIn(s)>=0);
265 }
266 else if(contains.at(i)==NOTREGEXP){
267 QRegExp regExp(t);
268 regExp.setCaseSensitivity(csens);
269 okPartial.append(regExp.indexIn(s)<0);
270 }
271 #endif
272 else
273 assert(0);
274 }
275
276 if(all){
277 bool ok=true;
278 for(bool b : qAsConst(okPartial))
279 ok = ok && b;
280
281 return ok;
282 }
283 else{ //any
284 bool ok=false;
285 for(bool b : qAsConst(okPartial))
286 ok = ok || b;
287
288 return ok;
289 }
290 }
291
moveSpaceConstraintUp()292 void AllSpaceConstraintsForm::moveSpaceConstraintUp()
293 {
294 if(filterCheckBox->isChecked()){
295 QMessageBox::information(this, tr("FET information"), tr("To move a space constraint, the 'Filter' check box must not be checked."));
296 return;
297 }
298 if(sortedCheckBox->isChecked()){
299 QMessageBox::information(this, tr("FET information"), tr("To move a space constraint, the 'Sorted' check box must not be checked."));
300 return;
301 }
302
303 if(constraintsListWidget->count()<=1)
304 return;
305 int i=constraintsListWidget->currentRow();
306 if(i<0 || i>=constraintsListWidget->count())
307 return;
308 if(i==0)
309 return;
310
311 QString s1=constraintsListWidget->item(i)->text();
312 QString s2=constraintsListWidget->item(i-1)->text();
313
314 assert(gt.rules.spaceConstraintsList.count()==visibleSpaceConstraintsList.count());
315 SpaceConstraint* sc1=gt.rules.spaceConstraintsList.at(i);
316 assert(sc1==visibleSpaceConstraintsList.at(i));
317 SpaceConstraint* sc2=gt.rules.spaceConstraintsList.at(i-1);
318 assert(sc2==visibleSpaceConstraintsList.at(i-1));
319
320 gt.rules.internalStructureComputed=false;
321 setRulesModifiedAndOtherThings(>.rules);
322
323 constraintsListWidget->item(i)->setText(s2);
324 constraintsListWidget->item(i-1)->setText(s1);
325
326 gt.rules.spaceConstraintsList[i]=sc2;
327 gt.rules.spaceConstraintsList[i-1]=sc1;
328
329 visibleSpaceConstraintsList[i]=sc2;
330 visibleSpaceConstraintsList[i-1]=sc1;
331
332 if(USE_GUI_COLORS){
333 if(sc2->active)
334 constraintsListWidget->item(i)->setBackground(constraintsListWidget->palette().base());
335 else
336 constraintsListWidget->item(i)->setBackground(constraintsListWidget->palette().alternateBase());
337
338 if(sc1->active)
339 constraintsListWidget->item(i-1)->setBackground(constraintsListWidget->palette().base());
340 else
341 constraintsListWidget->item(i-1)->setBackground(constraintsListWidget->palette().alternateBase());
342 }
343
344 constraintsListWidget->setCurrentRow(i-1);
345 constraintChanged(/*i-1*/);
346 }
347
moveSpaceConstraintDown()348 void AllSpaceConstraintsForm::moveSpaceConstraintDown()
349 {
350 if(filterCheckBox->isChecked()){
351 QMessageBox::information(this, tr("FET information"), tr("To move a space constraint, the 'Filter' check box must not be checked."));
352 return;
353 }
354 if(sortedCheckBox->isChecked()){
355 QMessageBox::information(this, tr("FET information"), tr("To move a space constraint, the 'Sorted' check box must not be checked."));
356 return;
357 }
358
359 if(constraintsListWidget->count()<=1)
360 return;
361 int i=constraintsListWidget->currentRow();
362 if(i<0 || i>=constraintsListWidget->count())
363 return;
364 if(i==constraintsListWidget->count()-1)
365 return;
366
367 QString s1=constraintsListWidget->item(i)->text();
368 QString s2=constraintsListWidget->item(i+1)->text();
369
370 assert(gt.rules.spaceConstraintsList.count()==visibleSpaceConstraintsList.count());
371 SpaceConstraint* sc1=gt.rules.spaceConstraintsList.at(i);
372 assert(sc1==visibleSpaceConstraintsList.at(i));
373 SpaceConstraint* sc2=gt.rules.spaceConstraintsList.at(i+1);
374 assert(sc2==visibleSpaceConstraintsList.at(i+1));
375
376 gt.rules.internalStructureComputed=false;
377 setRulesModifiedAndOtherThings(>.rules);
378
379 constraintsListWidget->item(i)->setText(s2);
380 constraintsListWidget->item(i+1)->setText(s1);
381
382 gt.rules.spaceConstraintsList[i]=sc2;
383 gt.rules.spaceConstraintsList[i+1]=sc1;
384
385 visibleSpaceConstraintsList[i]=sc2;
386 visibleSpaceConstraintsList[i+1]=sc1;
387
388 if(USE_GUI_COLORS){
389 if(sc2->active)
390 constraintsListWidget->item(i)->setBackground(constraintsListWidget->palette().base());
391 else
392 constraintsListWidget->item(i)->setBackground(constraintsListWidget->palette().alternateBase());
393
394 if(sc1->active)
395 constraintsListWidget->item(i+1)->setBackground(constraintsListWidget->palette().base());
396 else
397 constraintsListWidget->item(i+1)->setBackground(constraintsListWidget->palette().alternateBase());
398 }
399
400 constraintsListWidget->setCurrentRow(i+1);
401 constraintChanged(/*i+1*/);
402 }
403
sortedChanged(bool checked)404 void AllSpaceConstraintsForm::sortedChanged(bool checked)
405 {
406 Q_UNUSED(checked);
407
408 filterChanged();
409 }
410
spaceConstraintsAscendingByDescription(SpaceConstraint * s1,SpaceConstraint * s2)411 static int spaceConstraintsAscendingByDescription(SpaceConstraint* s1, SpaceConstraint* s2)
412 {
413 //return s1->getDescription(gt.rules) < s2->getDescription(gt.rules);
414 //by Rodolfo Ribeiro Gomes
415 return s1->getDescription(gt.rules).localeAwareCompare(s2->getDescription(gt.rules))<0;
416 }
417
filterChanged()418 void AllSpaceConstraintsForm::filterChanged()
419 {
420 visibleSpaceConstraintsList.clear();
421 constraintsListWidget->clear();
422 int n_active=0;
423 for(SpaceConstraint* ctr : qAsConst(gt.rules.spaceConstraintsList))
424 if(filterOk(ctr))
425 visibleSpaceConstraintsList.append(ctr);
426
427 if(sortedCheckBox->isChecked())
428 std::stable_sort(visibleSpaceConstraintsList.begin(), visibleSpaceConstraintsList.end(), spaceConstraintsAscendingByDescription);
429
430 for(SpaceConstraint* ctr : qAsConst(visibleSpaceConstraintsList)){
431 assert(filterOk(ctr));
432 constraintsListWidget->addItem(ctr->getDescription(gt.rules));
433
434 if(ctr->active)
435 n_active++;
436 else if(USE_GUI_COLORS)
437 constraintsListWidget->item(constraintsListWidget->count()-1)->setBackground(constraintsListWidget->palette().alternateBase());
438 }
439
440 if(constraintsListWidget->count()<=0)
441 currentConstraintTextEdit->setPlainText("");
442 else
443 constraintsListWidget->setCurrentRow(0);
444
445 constraintsTextLabel->setText(tr("%1 / %2 space constraints",
446 "%1 represents the number of visible active space constraints, %2 represents the total number of visible space constraints")
447 .arg(n_active).arg(visibleSpaceConstraintsList.count()));
448 }
449
constraintChanged()450 void AllSpaceConstraintsForm::constraintChanged()
451 {
452 int index=constraintsListWidget->currentRow();
453
454 if(index<0)
455 return;
456
457 assert(index<visibleSpaceConstraintsList.count());
458 SpaceConstraint* ctr=visibleSpaceConstraintsList.at(index);
459 assert(ctr!=nullptr);
460 QString s=ctr->getDetailedDescription(gt.rules);
461 currentConstraintTextEdit->setPlainText(s);
462 }
463
modifyConstraint()464 void AllSpaceConstraintsForm::modifyConstraint()
465 {
466 int i=constraintsListWidget->currentRow();
467 if(i<0){
468 QMessageBox::information(this, tr("FET information"), tr("Invalid selected constraint"));
469
470 constraintsListWidget->setFocus();
471
472 return;
473 }
474
475 int valv=constraintsListWidget->verticalScrollBar()->value();
476 int valh=constraintsListWidget->horizontalScrollBar()->value();
477
478 assert(i<visibleSpaceConstraintsList.count());
479 SpaceConstraint* ctr=visibleSpaceConstraintsList.at(i);
480
481 //1
482 if(ctr->type==CONSTRAINT_BASIC_COMPULSORY_SPACE){
483 ModifyConstraintBasicCompulsorySpaceForm form(this, (ConstraintBasicCompulsorySpace*)ctr);
484 setParentAndOtherThings(&form, this);
485 form.exec();
486 }
487 //2
488 else if(ctr->type==CONSTRAINT_ROOM_NOT_AVAILABLE_TIMES){
489 ModifyConstraintRoomNotAvailableTimesForm form(this, (ConstraintRoomNotAvailableTimes*)ctr);
490 setParentAndOtherThings(&form, this);
491 form.exec();
492 }
493 //3
494 else if(ctr->type==CONSTRAINT_ACTIVITY_PREFERRED_ROOM){
495 ModifyConstraintActivityPreferredRoomForm form(this, (ConstraintActivityPreferredRoom*)ctr);
496 setParentAndOtherThings(&form, this);
497 form.exec();
498 }
499 //4
500 else if(ctr->type==CONSTRAINT_ACTIVITY_PREFERRED_ROOMS){
501 ModifyConstraintActivityPreferredRoomsForm form(this, (ConstraintActivityPreferredRooms*)ctr);
502 setParentAndOtherThings(&form, this);
503 form.exec();
504 }
505 //5
506 else if(ctr->type==CONSTRAINT_STUDENTS_SET_HOME_ROOM){
507 ModifyConstraintStudentsSetHomeRoomForm form(this, (ConstraintStudentsSetHomeRoom*)ctr);
508 setParentAndOtherThings(&form, this);
509 form.exec();
510 }
511 //6
512 else if(ctr->type==CONSTRAINT_STUDENTS_SET_HOME_ROOMS){
513 ModifyConstraintStudentsSetHomeRoomsForm form(this, (ConstraintStudentsSetHomeRooms*)ctr);
514 setParentAndOtherThings(&form, this);
515 form.exec();
516 }
517 //7
518 else if(ctr->type==CONSTRAINT_TEACHER_HOME_ROOM){
519 ModifyConstraintTeacherHomeRoomForm form(this, (ConstraintTeacherHomeRoom*)ctr);
520 setParentAndOtherThings(&form, this);
521 form.exec();
522 }
523 //8
524 else if(ctr->type==CONSTRAINT_TEACHER_HOME_ROOMS){
525 ModifyConstraintTeacherHomeRoomsForm form(this, (ConstraintTeacherHomeRooms*)ctr);
526 setParentAndOtherThings(&form, this);
527 form.exec();
528 }
529 //9
530 else if(ctr->type==CONSTRAINT_SUBJECT_PREFERRED_ROOM){
531 ModifyConstraintSubjectPreferredRoomForm form(this, (ConstraintSubjectPreferredRoom*)ctr);
532 setParentAndOtherThings(&form, this);
533 form.exec();
534 }
535 //10
536 else if(ctr->type==CONSTRAINT_SUBJECT_PREFERRED_ROOMS){
537 ModifyConstraintSubjectPreferredRoomsForm form(this, (ConstraintSubjectPreferredRooms*)ctr);
538 setParentAndOtherThings(&form, this);
539 form.exec();
540 }
541 //11
542 else if(ctr->type==CONSTRAINT_SUBJECT_ACTIVITY_TAG_PREFERRED_ROOM){
543 ModifyConstraintSubjectActivityTagPreferredRoomForm form(this, (ConstraintSubjectActivityTagPreferredRoom*)ctr);
544 setParentAndOtherThings(&form, this);
545 form.exec();
546 }
547 //12
548 else if(ctr->type==CONSTRAINT_SUBJECT_ACTIVITY_TAG_PREFERRED_ROOMS){
549 ModifyConstraintSubjectActivityTagPreferredRoomsForm form(this, (ConstraintSubjectActivityTagPreferredRooms*)ctr);
550 setParentAndOtherThings(&form, this);
551 form.exec();
552 }
553 ///6 apr 2009
554 //13
555 else if(ctr->type==CONSTRAINT_ACTIVITY_TAG_PREFERRED_ROOM){
556 ModifyConstraintActivityTagPreferredRoomForm form(this, (ConstraintActivityTagPreferredRoom*)ctr);
557 setParentAndOtherThings(&form, this);
558 form.exec();
559 }
560 //14
561 else if(ctr->type==CONSTRAINT_ACTIVITY_TAG_PREFERRED_ROOMS){
562 ModifyConstraintActivityTagPreferredRoomsForm form(this, (ConstraintActivityTagPreferredRooms*)ctr);
563 setParentAndOtherThings(&form, this);
564 form.exec();
565 }
566 ///
567 //15
568 else if(ctr->type==CONSTRAINT_STUDENTS_SET_MAX_BUILDING_CHANGES_PER_DAY){
569 ModifyConstraintStudentsSetMaxBuildingChangesPerDayForm form(this, (ConstraintStudentsSetMaxBuildingChangesPerDay*)ctr);
570 setParentAndOtherThings(&form, this);
571 form.exec();
572 }
573 //16
574 else if(ctr->type==CONSTRAINT_STUDENTS_MAX_BUILDING_CHANGES_PER_DAY){
575 ModifyConstraintStudentsMaxBuildingChangesPerDayForm form(this, (ConstraintStudentsMaxBuildingChangesPerDay*)ctr);
576 setParentAndOtherThings(&form, this);
577 form.exec();
578 }
579 //17
580 else if(ctr->type==CONSTRAINT_STUDENTS_SET_MAX_BUILDING_CHANGES_PER_WEEK){
581 ModifyConstraintStudentsSetMaxBuildingChangesPerWeekForm form(this, (ConstraintStudentsSetMaxBuildingChangesPerWeek*)ctr);
582 setParentAndOtherThings(&form, this);
583 form.exec();
584 }
585 //18
586 else if(ctr->type==CONSTRAINT_STUDENTS_MAX_BUILDING_CHANGES_PER_WEEK){
587 ModifyConstraintStudentsMaxBuildingChangesPerWeekForm form(this, (ConstraintStudentsMaxBuildingChangesPerWeek*)ctr);
588 setParentAndOtherThings(&form, this);
589 form.exec();
590 }
591 //19
592 else if(ctr->type==CONSTRAINT_STUDENTS_SET_MIN_GAPS_BETWEEN_BUILDING_CHANGES){
593 ModifyConstraintStudentsSetMinGapsBetweenBuildingChangesForm form(this, (ConstraintStudentsSetMinGapsBetweenBuildingChanges*)ctr);
594 setParentAndOtherThings(&form, this);
595 form.exec();
596 }
597 //20
598 else if(ctr->type==CONSTRAINT_STUDENTS_MIN_GAPS_BETWEEN_BUILDING_CHANGES){
599 ModifyConstraintStudentsMinGapsBetweenBuildingChangesForm form(this, (ConstraintStudentsMinGapsBetweenBuildingChanges*)ctr);
600 setParentAndOtherThings(&form, this);
601 form.exec();
602 }
603 //21
604 else if(ctr->type==CONSTRAINT_TEACHER_MAX_BUILDING_CHANGES_PER_DAY){
605 ModifyConstraintTeacherMaxBuildingChangesPerDayForm form(this, (ConstraintTeacherMaxBuildingChangesPerDay*)ctr);
606 setParentAndOtherThings(&form, this);
607 form.exec();
608 }
609 //22
610 else if(ctr->type==CONSTRAINT_TEACHERS_MAX_BUILDING_CHANGES_PER_DAY){
611 ModifyConstraintTeachersMaxBuildingChangesPerDayForm form(this, (ConstraintTeachersMaxBuildingChangesPerDay*)ctr);
612 setParentAndOtherThings(&form, this);
613 form.exec();
614 }
615 //23
616 else if(ctr->type==CONSTRAINT_TEACHER_MAX_BUILDING_CHANGES_PER_WEEK){
617 ModifyConstraintTeacherMaxBuildingChangesPerWeekForm form(this, (ConstraintTeacherMaxBuildingChangesPerWeek*)ctr);
618 setParentAndOtherThings(&form, this);
619 form.exec();
620 }
621 //24
622 else if(ctr->type==CONSTRAINT_TEACHERS_MAX_BUILDING_CHANGES_PER_WEEK){
623 ModifyConstraintTeachersMaxBuildingChangesPerWeekForm form(this, (ConstraintTeachersMaxBuildingChangesPerWeek*)ctr);
624 setParentAndOtherThings(&form, this);
625 form.exec();
626 }
627 //25
628 else if(ctr->type==CONSTRAINT_TEACHER_MIN_GAPS_BETWEEN_BUILDING_CHANGES){
629 ModifyConstraintTeacherMinGapsBetweenBuildingChangesForm form(this, (ConstraintTeacherMinGapsBetweenBuildingChanges*)ctr);
630 setParentAndOtherThings(&form, this);
631 form.exec();
632 }
633 //26
634 else if(ctr->type==CONSTRAINT_TEACHERS_MIN_GAPS_BETWEEN_BUILDING_CHANGES){
635 ModifyConstraintTeachersMinGapsBetweenBuildingChangesForm form(this, (ConstraintTeachersMinGapsBetweenBuildingChanges*)ctr);
636 setParentAndOtherThings(&form, this);
637 form.exec();
638 }
639 //27
640 else if(ctr->type==CONSTRAINT_ACTIVITIES_OCCUPY_MAX_DIFFERENT_ROOMS){
641 ModifyConstraintActivitiesOccupyMaxDifferentRoomsForm form(this, (ConstraintActivitiesOccupyMaxDifferentRooms*)ctr);
642 setParentAndOtherThings(&form, this);
643 form.exec();
644 }
645 //28
646 else if(ctr->type==CONSTRAINT_ACTIVITIES_SAME_ROOM_IF_CONSECUTIVE){
647 ModifyConstraintActivitiesSameRoomIfConsecutiveForm form(this, (ConstraintActivitiesSameRoomIfConsecutive*)ctr);
648 setParentAndOtherThings(&form, this);
649 form.exec();
650 }
651 //2019-11-14
652 //29
653 else if(ctr->type==CONSTRAINT_STUDENTS_SET_MAX_ROOM_CHANGES_PER_DAY){
654 ModifyConstraintStudentsSetMaxRoomChangesPerDayForm form(this, (ConstraintStudentsSetMaxRoomChangesPerDay*)ctr);
655 setParentAndOtherThings(&form, this);
656 form.exec();
657 }
658 //30
659 else if(ctr->type==CONSTRAINT_STUDENTS_MAX_ROOM_CHANGES_PER_DAY){
660 ModifyConstraintStudentsMaxRoomChangesPerDayForm form(this, (ConstraintStudentsMaxRoomChangesPerDay*)ctr);
661 setParentAndOtherThings(&form, this);
662 form.exec();
663 }
664 //31
665 else if(ctr->type==CONSTRAINT_STUDENTS_SET_MAX_ROOM_CHANGES_PER_WEEK){
666 ModifyConstraintStudentsSetMaxRoomChangesPerWeekForm form(this, (ConstraintStudentsSetMaxRoomChangesPerWeek*)ctr);
667 setParentAndOtherThings(&form, this);
668 form.exec();
669 }
670 //32
671 else if(ctr->type==CONSTRAINT_STUDENTS_MAX_ROOM_CHANGES_PER_WEEK){
672 ModifyConstraintStudentsMaxRoomChangesPerWeekForm form(this, (ConstraintStudentsMaxRoomChangesPerWeek*)ctr);
673 setParentAndOtherThings(&form, this);
674 form.exec();
675 }
676 //33
677 else if(ctr->type==CONSTRAINT_STUDENTS_SET_MIN_GAPS_BETWEEN_ROOM_CHANGES){
678 ModifyConstraintStudentsSetMinGapsBetweenRoomChangesForm form(this, (ConstraintStudentsSetMinGapsBetweenRoomChanges*)ctr);
679 setParentAndOtherThings(&form, this);
680 form.exec();
681 }
682 //34
683 else if(ctr->type==CONSTRAINT_STUDENTS_MIN_GAPS_BETWEEN_ROOM_CHANGES){
684 ModifyConstraintStudentsMinGapsBetweenRoomChangesForm form(this, (ConstraintStudentsMinGapsBetweenRoomChanges*)ctr);
685 setParentAndOtherThings(&form, this);
686 form.exec();
687 }
688 //35
689 else if(ctr->type==CONSTRAINT_TEACHER_MAX_ROOM_CHANGES_PER_DAY){
690 ModifyConstraintTeacherMaxRoomChangesPerDayForm form(this, (ConstraintTeacherMaxRoomChangesPerDay*)ctr);
691 setParentAndOtherThings(&form, this);
692 form.exec();
693 }
694 //36
695 else if(ctr->type==CONSTRAINT_TEACHERS_MAX_ROOM_CHANGES_PER_DAY){
696 ModifyConstraintTeachersMaxRoomChangesPerDayForm form(this, (ConstraintTeachersMaxRoomChangesPerDay*)ctr);
697 setParentAndOtherThings(&form, this);
698 form.exec();
699 }
700 //37
701 else if(ctr->type==CONSTRAINT_TEACHER_MAX_ROOM_CHANGES_PER_WEEK){
702 ModifyConstraintTeacherMaxRoomChangesPerWeekForm form(this, (ConstraintTeacherMaxRoomChangesPerWeek*)ctr);
703 setParentAndOtherThings(&form, this);
704 form.exec();
705 }
706 //38
707 else if(ctr->type==CONSTRAINT_TEACHERS_MAX_ROOM_CHANGES_PER_WEEK){
708 ModifyConstraintTeachersMaxRoomChangesPerWeekForm form(this, (ConstraintTeachersMaxRoomChangesPerWeek*)ctr);
709 setParentAndOtherThings(&form, this);
710 form.exec();
711 }
712 //39
713 else if(ctr->type==CONSTRAINT_TEACHER_MIN_GAPS_BETWEEN_ROOM_CHANGES){
714 ModifyConstraintTeacherMinGapsBetweenRoomChangesForm form(this, (ConstraintTeacherMinGapsBetweenRoomChanges*)ctr);
715 setParentAndOtherThings(&form, this);
716 form.exec();
717 }
718 //40
719 else if(ctr->type==CONSTRAINT_TEACHERS_MIN_GAPS_BETWEEN_ROOM_CHANGES){
720 ModifyConstraintTeachersMinGapsBetweenRoomChangesForm form(this, (ConstraintTeachersMinGapsBetweenRoomChanges*)ctr);
721 setParentAndOtherThings(&form, this);
722 form.exec();
723 }
724 //41
725 else if(ctr->type==CONSTRAINT_TEACHER_ROOM_NOT_AVAILABLE_TIMES){
726 ModifyConstraintTeacherRoomNotAvailableTimesForm form(this, (ConstraintTeacherRoomNotAvailableTimes*)ctr);
727 setParentAndOtherThings(&form, this);
728 form.exec();
729 }
730 //for mornings-afternoons
731 //42
732 else if(ctr->type==CONSTRAINT_STUDENTS_SET_MAX_ROOM_CHANGES_PER_REAL_DAY){
733 ModifyConstraintStudentsSetMaxRoomChangesPerRealDayForm form(this, (ConstraintStudentsSetMaxRoomChangesPerRealDay*)ctr);
734 setParentAndOtherThings(&form, this);
735 form.exec();
736 }
737 //43
738 else if(ctr->type==CONSTRAINT_STUDENTS_MAX_ROOM_CHANGES_PER_REAL_DAY){
739 ModifyConstraintStudentsMaxRoomChangesPerRealDayForm form(this, (ConstraintStudentsMaxRoomChangesPerRealDay*)ctr);
740 setParentAndOtherThings(&form, this);
741 form.exec();
742 }
743 //44
744 else if(ctr->type==CONSTRAINT_TEACHER_MAX_ROOM_CHANGES_PER_REAL_DAY){
745 ModifyConstraintTeacherMaxRoomChangesPerRealDayForm form(this, (ConstraintTeacherMaxRoomChangesPerRealDay*)ctr);
746 setParentAndOtherThings(&form, this);
747 form.exec();
748 }
749 //45
750 else if(ctr->type==CONSTRAINT_TEACHERS_MAX_ROOM_CHANGES_PER_REAL_DAY){
751 ModifyConstraintTeachersMaxRoomChangesPerRealDayForm form(this, (ConstraintTeachersMaxRoomChangesPerRealDay*)ctr);
752 setParentAndOtherThings(&form, this);
753 form.exec();
754 }
755 else{
756 QMessageBox::critical(this, tr("FET critical"), tr("You have found a bug in FET. Please report it. This kind of constraint"
757 " is not correctly recognized in all space constraints dialog. FET will skip this error, so that you can continue work."
758 " Probably the constraint can be modified from the specific constraint dialog."));
759 // assert(0);
760 // exit(1);
761 }
762
763 filterChanged();
764
765 constraintsListWidget->verticalScrollBar()->setValue(valv);
766 constraintsListWidget->horizontalScrollBar()->setValue(valh);
767
768 if(i>=constraintsListWidget->count())
769 i=constraintsListWidget->count()-1;
770
771 if(i>=0)
772 constraintsListWidget->setCurrentRow(i);
773
774 constraintsListWidget->setFocus();
775 }
776
removeConstraint()777 void AllSpaceConstraintsForm::removeConstraint()
778 {
779 int i=constraintsListWidget->currentRow();
780 if(i<0){
781 QMessageBox::information(this, tr("FET information"), tr("Invalid selected constraint"));
782 return;
783 }
784 assert(i<visibleSpaceConstraintsList.count());
785 SpaceConstraint* ctr=visibleSpaceConstraintsList.at(i);
786
787 QString s;
788 s=tr("Remove constraint?");
789 s+="\n\n";
790 s+=ctr->getDetailedDescription(gt.rules);
791
792 bool recompute, t;
793
794 QListWidgetItem* item;
795
796 int lres=LongTextMessageBox::confirmation( this, tr("FET confirmation"),
797 s, tr("Yes"), tr("No"), 0, 0, 1 );
798
799 if(lres==0){ //The user clicked the OK button or pressed Enter
800 QMessageBox::StandardButton wr=QMessageBox::Yes;
801
802 if(ctr->type==CONSTRAINT_BASIC_COMPULSORY_SPACE){ //additional confirmation for this one
803 QString s=tr("Do you really want to remove the basic compulsory space constraint?");
804 s+=" ";
805 s+=tr("You cannot generate a timetable without this constraint.");
806 s+="\n\n";
807 s+=tr("Note: you can add again a constraint of this type from the menu Data -> Space constraints -> "
808 "Miscellaneous -> Basic compulsory space constraints.");
809
810 wr=QMessageBox::warning(this, tr("FET warning"), s,
811 QMessageBox::Yes|QMessageBox::No, QMessageBox::No);
812 }
813
814 if(wr==QMessageBox::Yes){
815 if(ctr->type==CONSTRAINT_ACTIVITY_PREFERRED_ROOM){
816 recompute=true;
817 }
818 else{
819 recompute=false;
820 }
821
822 t=gt.rules.removeSpaceConstraint(ctr);
823 assert(t);
824 visibleSpaceConstraintsList.removeAt(i);
825 constraintsListWidget->setCurrentRow(-1);
826 item=constraintsListWidget->takeItem(i);
827 delete item;
828
829 int n_active=0;
830 for(SpaceConstraint* ctr2 : qAsConst(visibleSpaceConstraintsList))
831 if(ctr2->active)
832 n_active++;
833
834 constraintsTextLabel->setText(tr("%1 / %2 space constraints",
835 "%1 represents the number of visible active space constraints, %2 represents the total number of visible space constraints")
836 .arg(n_active).arg(visibleSpaceConstraintsList.count()));
837
838 //constraintsTextLabel->setText(tr("%1 Space Constraints", "%1 represents the number of constraints").arg(visibleSpaceConstraintsList.count()));
839
840 if(recompute){
841 LockUnlock::computeLockedUnlockedActivitiesOnlySpace();
842 LockUnlock::increaseCommunicationSpinBox();
843 }
844 }
845 }
846 //else if(lres==1){ //The user clicked the Cancel button or pressed Escape
847 //}
848
849 if(i>=constraintsListWidget->count())
850 i=constraintsListWidget->count()-1;
851 if(i>=0)
852 constraintsListWidget->setCurrentRow(i);
853 else
854 currentConstraintTextEdit->setPlainText(QString(""));
855 }
856
filter(bool active)857 void AllSpaceConstraintsForm::filter(bool active)
858 {
859 if(!active){
860 assert(useFilter==true);
861 useFilter=false;
862
863 filterChanged();
864
865 return;
866 }
867
868 assert(active);
869
870 filterForm=new AdvancedFilterForm(this, all, descrDetDescr, contains, text, caseSensitive, "AllSpaceConstraintsAdvancedFilterForm");
871
872 int t=filterForm->exec();
873
874 if(t==QDialog::Accepted){
875 assert(useFilter==false);
876 useFilter=true;
877
878 if(filterForm->allRadio->isChecked())
879 all=true;
880 else if(filterForm->anyRadio->isChecked())
881 all=false;
882 else
883 assert(0);
884
885 caseSensitive=filterForm->caseSensitiveCheckBox->isChecked();
886
887 descrDetDescr.clear();
888 contains.clear();
889 text.clear();
890
891 assert(filterForm->descrDetDescrComboBoxList.count()==filterForm->contNContReNReComboBoxList.count());
892 assert(filterForm->descrDetDescrComboBoxList.count()==filterForm->textLineEditList.count());
893 for(int i=0; i<filterForm->rows; i++){
894 QComboBox* cb1=filterForm->descrDetDescrComboBoxList.at(i);
895 QComboBox* cb2=filterForm->contNContReNReComboBoxList.at(i);
896 QLineEdit* tl=filterForm->textLineEditList.at(i);
897
898 descrDetDescr.append(cb1->currentIndex());
899 contains.append(cb2->currentIndex());
900 text.append(tl->text());
901 }
902
903 filterChanged();
904 }
905 else{
906 assert(useFilter==false);
907 useFilter=false;
908
909 disconnect(filterCheckBox, SIGNAL(toggled(bool)), this, SLOT(filter(bool)));
910 filterCheckBox->setChecked(false);
911 connect(filterCheckBox, SIGNAL(toggled(bool)), this, SLOT(filter(bool)));
912 }
913
914 delete filterForm;
915 }
916
activateConstraint()917 void AllSpaceConstraintsForm::activateConstraint()
918 {
919 int i=constraintsListWidget->currentRow();
920 if(i<0){
921 QMessageBox::information(this, tr("FET information"), tr("Invalid selected constraint"));
922
923 constraintsListWidget->setFocus();
924
925 return;
926 }
927
928 assert(i<visibleSpaceConstraintsList.count());
929 SpaceConstraint* ctr=visibleSpaceConstraintsList.at(i);
930
931 if(!ctr->active){
932 ctr->active=true;
933
934 gt.rules.internalStructureComputed=false;
935 setRulesModifiedAndOtherThings(>.rules);
936
937 if(!filterOk(ctr)){ //Maybe the constraint is no longer visible in the list widget, because of the filter.
938 visibleSpaceConstraintsList.removeAt(i);
939 constraintsListWidget->setCurrentRow(-1);
940 QListWidgetItem* item=constraintsListWidget->takeItem(i);
941 delete item;
942
943 if(i>=constraintsListWidget->count())
944 i=constraintsListWidget->count()-1;
945 if(i>=0)
946 constraintsListWidget->setCurrentRow(i);
947 else
948 currentConstraintTextEdit->setPlainText(QString(""));
949 }
950 else{
951 constraintsListWidget->currentItem()->setText(ctr->getDescription(gt.rules));
952 if(USE_GUI_COLORS)
953 constraintsListWidget->currentItem()->setBackground(constraintsListWidget->palette().base());
954 constraintChanged();
955 }
956
957 if(ctr->type==CONSTRAINT_ACTIVITY_PREFERRED_ROOM){
958 LockUnlock::computeLockedUnlockedActivitiesOnlySpace();
959 LockUnlock::increaseCommunicationSpinBox();
960 }
961
962 int n_active=0;
963 for(SpaceConstraint* ctr2 : qAsConst(visibleSpaceConstraintsList))
964 if(ctr2->active)
965 n_active++;
966
967 constraintsTextLabel->setText(tr("%1 / %2 space constraints",
968 "%1 represents the number of visible active space constraints, %2 represents the total number of visible space constraints")
969 .arg(n_active).arg(visibleSpaceConstraintsList.count()));
970 }
971
972 constraintsListWidget->setFocus();
973 }
974
deactivateConstraint()975 void AllSpaceConstraintsForm::deactivateConstraint()
976 {
977 int i=constraintsListWidget->currentRow();
978 if(i<0){
979 QMessageBox::information(this, tr("FET information"), tr("Invalid selected constraint"));
980
981 constraintsListWidget->setFocus();
982
983 return;
984 }
985
986 assert(i<visibleSpaceConstraintsList.count());
987 SpaceConstraint* ctr=visibleSpaceConstraintsList.at(i);
988
989 if(ctr->active){
990 if(ctr->type==CONSTRAINT_BASIC_COMPULSORY_SPACE){
991 QMessageBox::warning(this, tr("FET warning"), tr("You are not allowed to deactivate the basic compulsory space constraints"));
992 return;
993 }
994
995 ctr->active=false;
996
997 gt.rules.internalStructureComputed=false;
998 setRulesModifiedAndOtherThings(>.rules);
999
1000 if(!filterOk(ctr)){ //Maybe the constraint is no longer visible in the list widget, because of the filter.
1001 visibleSpaceConstraintsList.removeAt(i);
1002 constraintsListWidget->setCurrentRow(-1);
1003 QListWidgetItem* item=constraintsListWidget->takeItem(i);
1004 delete item;
1005
1006 if(i>=constraintsListWidget->count())
1007 i=constraintsListWidget->count()-1;
1008 if(i>=0)
1009 constraintsListWidget->setCurrentRow(i);
1010 else
1011 currentConstraintTextEdit->setPlainText(QString(""));
1012 }
1013 else{
1014 constraintsListWidget->currentItem()->setText(ctr->getDescription(gt.rules));
1015 if(USE_GUI_COLORS)
1016 constraintsListWidget->currentItem()->setBackground(constraintsListWidget->palette().alternateBase());
1017 constraintChanged();
1018 }
1019
1020 if(ctr->type==CONSTRAINT_ACTIVITY_PREFERRED_ROOM){
1021 LockUnlock::computeLockedUnlockedActivitiesOnlySpace();
1022 LockUnlock::increaseCommunicationSpinBox();
1023 }
1024
1025 int n_active=0;
1026 for(SpaceConstraint* ctr2 : qAsConst(visibleSpaceConstraintsList))
1027 if(ctr2->active)
1028 n_active++;
1029
1030 constraintsTextLabel->setText(tr("%1 / %2 space constraints",
1031 "%1 represents the number of visible active space constraints, %2 represents the total number of visible space constraints")
1032 .arg(n_active).arg(visibleSpaceConstraintsList.count()));
1033 }
1034
1035 constraintsListWidget->setFocus();
1036 }
1037
1038 /*static int spaceConstraintsAscendingByComments(const SpaceConstraint* s1, const SpaceConstraint* s2)
1039 {
1040 return s1->comments < s2->comments;
1041 }
1042
1043 void AllSpaceConstraintsForm::sortConstraintsByComments()
1044 {
1045 QMessageBox::StandardButton t=QMessageBox::question(this, tr("Sort constraints?"),
1046 tr("This will sort the space constraints list ascending according to their comments. You can obtain "
1047 "a custom ordering by adding comments to some or all space constraints, for example 'rank #1 ... other comments', "
1048 "'rank #2 ... other different comments'.")
1049 +" "+tr("Are you sure you want to continue?"),
1050 QMessageBox::Yes|QMessageBox::Cancel);
1051
1052 if(t==QMessageBox::Cancel)
1053 return;
1054
1055 std::stable_sort(gt.rules.spaceConstraintsList.begin(), gt.rules.spaceConstraintsList.end(), spaceConstraintsAscendingByComments);
1056
1057 gt.rules.internalStructureComputed=false;
1058 setRulesModifiedAndOtherThings(>.rules);
1059
1060 filterChanged();
1061 }*/
1062
constraintComments()1063 void AllSpaceConstraintsForm::constraintComments()
1064 {
1065 int i=constraintsListWidget->currentRow();
1066 if(i<0){
1067 QMessageBox::information(this, tr("FET information"), tr("Invalid selected constraint"));
1068 return;
1069 }
1070
1071 assert(i<visibleSpaceConstraintsList.count());
1072 SpaceConstraint* ctr=visibleSpaceConstraintsList.at(i);
1073
1074 QDialog getCommentsDialog(this);
1075
1076 getCommentsDialog.setWindowTitle(tr("Constraint comments"));
1077
1078 QPushButton* okPB=new QPushButton(tr("OK"));
1079 okPB->setDefault(true);
1080 QPushButton* cancelPB=new QPushButton(tr("Cancel"));
1081
1082 connect(okPB, SIGNAL(clicked()), &getCommentsDialog, SLOT(accept()));
1083 connect(cancelPB, SIGNAL(clicked()), &getCommentsDialog, SLOT(reject()));
1084
1085 QHBoxLayout* hl=new QHBoxLayout();
1086 hl->addStretch();
1087 hl->addWidget(okPB);
1088 hl->addWidget(cancelPB);
1089
1090 QVBoxLayout* vl=new QVBoxLayout();
1091
1092 QPlainTextEdit* commentsPT=new QPlainTextEdit();
1093 commentsPT->setPlainText(ctr->comments);
1094 commentsPT->selectAll();
1095 commentsPT->setFocus();
1096
1097 vl->addWidget(commentsPT);
1098 vl->addLayout(hl);
1099
1100 getCommentsDialog.setLayout(vl);
1101
1102 const QString settingsName=QString("SpaceConstraintCommentsDialog");
1103
1104 getCommentsDialog.resize(500, 320);
1105 centerWidgetOnScreen(&getCommentsDialog);
1106 restoreFETDialogGeometry(&getCommentsDialog, settingsName);
1107
1108 int t=getCommentsDialog.exec();
1109 saveFETDialogGeometry(&getCommentsDialog, settingsName);
1110
1111 if(t==QDialog::Accepted){
1112 ctr->comments=commentsPT->toPlainText();
1113
1114 gt.rules.internalStructureComputed=false;
1115 setRulesModifiedAndOtherThings(>.rules);
1116
1117 if(!filterOk(ctr)){ //Maybe the constraint is no longer visible in the list widget, because of the filter.
1118 visibleSpaceConstraintsList.removeAt(i);
1119 constraintsListWidget->setCurrentRow(-1);
1120 QListWidgetItem* item=constraintsListWidget->takeItem(i);
1121 delete item;
1122
1123 if(i>=constraintsListWidget->count())
1124 i=constraintsListWidget->count()-1;
1125 if(i>=0)
1126 constraintsListWidget->setCurrentRow(i);
1127 else
1128 currentConstraintTextEdit->setPlainText(QString(""));
1129
1130 int n_active=0;
1131 for(SpaceConstraint* ctr2 : qAsConst(visibleSpaceConstraintsList))
1132 if(ctr2->active)
1133 n_active++;
1134
1135 constraintsTextLabel->setText(tr("%1 / %2 space constraints",
1136 "%1 represents the number of visible active space constraints, %2 represents the total number of visible space constraints")
1137 .arg(n_active).arg(visibleSpaceConstraintsList.count()));
1138 }
1139 else{
1140 constraintsListWidget->currentItem()->setText(ctr->getDescription(gt.rules));
1141 constraintChanged();
1142 }
1143 }
1144 }
1145