1 //
2 //
3 // Description: This file is part of FET
4 //
5 //
6 // Author: Lalescu Liviu <Please see https://lalescu.ro/liviu/ for details about contacting Liviu Lalescu (in particular, you can find here the e-mail address)>
7 // Copyright (C) 2003 Liviu Lalescu <https://lalescu.ro/liviu/>
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 "addstudentssubgroupform.h"
19 #include "addexistingstudentssubgroupsform.h"
20 #include "modifystudentssubgroupform.h"
21 #include "subgroupsform.h"
22 #include "timetable_defs.h"
23 #include "timetable.h"
24 #include "fet.h"
25
26 #include "longtextmessagebox.h"
27
28 #include <QMessageBox>
29
30 #include <QListWidget>
31 #include <QScrollBar>
32 #include <QAbstractItemView>
33
34 #include <QSplitter>
35 #include <QSettings>
36 #include <QObject>
37 #include <QMetaObject>
38
39 #include <QSet>
40 #include <QList>
41 #include <QPair>
42
43 extern const QString COMPANY;
44 extern const QString PROGRAM;
45
46 extern bool students_schedule_ready;
47 extern bool rooms_schedule_ready;
48 extern bool teachers_schedule_ready;
49
SubgroupsForm(QWidget * parent)50 SubgroupsForm::SubgroupsForm(QWidget* parent): QDialog(parent)
51 {
52 setupUi(this);
53
54 subgroupTextEdit->setReadOnly(true);
55
56 modifySubgroupPushButton->setDefault(true);
57
58 yearsListWidget->setSelectionMode(QAbstractItemView::SingleSelection);
59 groupsListWidget->setSelectionMode(QAbstractItemView::SingleSelection);
60 subgroupsListWidget->setSelectionMode(QAbstractItemView::SingleSelection);
61
62 connect(yearsListWidget, SIGNAL(currentTextChanged(const QString&)), this, SLOT(yearChanged(const QString&)));
63 connect(groupsListWidget, SIGNAL(currentTextChanged(const QString&)), this, SLOT(groupChanged(const QString&)));
64 connect(addSubgroupPushButton, SIGNAL(clicked()), this, SLOT(addSubgroup()));
65 connect(addExistingSubgroupsPushButton, SIGNAL(clicked()), this, SLOT(addExistingSubgroups()));
66 connect(removeSubgroupPushButton, SIGNAL(clicked()), this, SLOT(removeSubgroup()));
67 connect(purgeSubgroupPushButton, SIGNAL(clicked()), this, SLOT(purgeSubgroup()));
68 connect(closePushButton, SIGNAL(clicked()), this, SLOT(close()));
69 connect(subgroupsListWidget, SIGNAL(currentTextChanged(const QString&)), this, SLOT(subgroupChanged(const QString&)));
70 connect(modifySubgroupPushButton, SIGNAL(clicked()), this, SLOT(modifySubgroup()));
71
72 connect(moveSubgroupUpPushButton, SIGNAL(clicked()), this, SLOT(moveSubgroupUp()));
73 connect(moveSubgroupDownPushButton, SIGNAL(clicked()), this, SLOT(moveSubgroupDown()));
74
75 connect(sortSubgroupsPushButton, SIGNAL(clicked()), this, SLOT(sortSubgroups()));
76 connect(activateStudentsPushButton, SIGNAL(clicked()), this, SLOT(activateStudents()));
77 connect(deactivateStudentsPushButton, SIGNAL(clicked()), this, SLOT(deactivateStudents()));
78 connect(subgroupsListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(modifySubgroup()));
79
80 connect(commentsPushButton, SIGNAL(clicked()), this, SLOT(comments()));
81
82 centerWidgetOnScreen(this);
83 restoreFETDialogGeometry(this);
84 //restore splitter state
85 QSettings settings(COMPANY, PROGRAM);
86 if(settings.contains(this->metaObject()->className()+QString("/splitter-state")))
87 splitter->restoreState(settings.value(this->metaObject()->className()+QString("/splitter-state")).toByteArray());
88
89 yearsListWidget->clear();
90 for(int i=0; i<gt.rules.yearsList.size(); i++){
91 StudentsYear* year=gt.rules.yearsList[i];
92 yearsListWidget->addItem(year->name);
93 }
94
95 if(yearsListWidget->count()>0)
96 yearsListWidget->setCurrentRow(0);
97 else{
98 groupsListWidget->clear();
99 subgroupsListWidget->clear();
100 }
101 }
102
~SubgroupsForm()103 SubgroupsForm::~SubgroupsForm()
104 {
105 saveFETDialogGeometry(this);
106 //save splitter state
107 QSettings settings(COMPANY, PROGRAM);
108 settings.setValue(this->metaObject()->className()+QString("/splitter-state"), splitter->saveState());
109 }
110
addSubgroup()111 void SubgroupsForm::addSubgroup()
112 {
113 if(yearsListWidget->currentRow()<0){
114 QMessageBox::information(this, tr("FET information"), tr("Invalid selected year"));
115 return;
116 }
117 QString yearName=yearsListWidget->currentItem()->text();
118 int yearIndex=gt.rules.searchYear(yearName);
119 assert(yearIndex>=0);
120
121 if(groupsListWidget->currentRow()<0){
122 QMessageBox::information(this, tr("FET information"), tr("Invalid selected group"));
123 return;
124 }
125 QString groupName=groupsListWidget->currentItem()->text();
126 int groupIndex=gt.rules.searchGroup(yearName, groupName);
127 assert(groupIndex>=0);
128
129 AddStudentsSubgroupForm form(this, yearName, groupName);
130 setParentAndOtherThings(&form, this);
131 form.exec();
132
133 groupChanged(groupsListWidget->currentItem()->text());
134
135 int i=subgroupsListWidget->count()-1;
136 if(i>=0)
137 subgroupsListWidget->setCurrentRow(i);
138 }
139
addExistingSubgroups()140 void SubgroupsForm::addExistingSubgroups()
141 {
142 if(yearsListWidget->currentRow()<0){
143 QMessageBox::information(this, tr("FET information"), tr("Invalid selected year"));
144 return;
145 }
146 QString yearName=yearsListWidget->currentItem()->text();
147
148 StudentsYear* year=nullptr;
149
150 for(StudentsYear* sty : qAsConst(gt.rules.yearsList))
151 if(sty->name==yearName){
152 year=sty;
153 break;
154 }
155
156 assert(year!=nullptr);
157
158 if(groupsListWidget->currentRow()<0){
159 QMessageBox::information(this, tr("FET information"), tr("Invalid selected group"));
160 return;
161 }
162 QString groupName=groupsListWidget->currentItem()->text();
163
164 StudentsGroup* group=nullptr;
165
166 for(StudentsGroup* stg : qAsConst(year->groupsList))
167 if(stg->name==groupName){
168 group=stg;
169 break;
170 }
171
172 assert(group!=nullptr);
173
174 AddExistingStudentsSubgroupsForm form(this, year, group);
175 setParentAndOtherThings(&form, this);
176 int t=form.exec();
177
178 if(t==QDialog::Accepted){
179 groupChanged(groupsListWidget->currentItem()->text());
180
181 int i=subgroupsListWidget->count()-1;
182 if(i>=0)
183 subgroupsListWidget->setCurrentRow(i);
184 }
185 else{
186 assert(t==QDialog::Rejected);
187 }
188 }
189
removeSubgroup()190 void SubgroupsForm::removeSubgroup()
191 {
192 if(yearsListWidget->currentRow()<0){
193 QMessageBox::information(this, tr("FET information"), tr("Invalid selected year"));
194 return;
195 }
196 QString yearName=yearsListWidget->currentItem()->text();
197 int yearIndex=gt.rules.searchYear(yearName);
198 assert(yearIndex>=0);
199
200 if(groupsListWidget->currentRow()<0){
201 QMessageBox::information(this, tr("FET information"), tr("Invalid selected group"));
202 return;
203 }
204 QString groupName=groupsListWidget->currentItem()->text();
205 int groupIndex=gt.rules.searchGroup(yearName, groupName);
206 assert(groupIndex>=0);
207
208 if(subgroupsListWidget->currentRow()<0){
209 QMessageBox::information(this, tr("FET information"), tr("Invalid selected subgroup"));
210 return;
211 }
212
213 QString subgroupName=subgroupsListWidget->currentItem()->text();
214 int subgroupIndex=gt.rules.searchSubgroup(yearName, groupName, subgroupName);
215 assert(subgroupIndex>=0);
216
217 QList<QPair<QString, QString>> yearsGroupsContainingSubgroup_List;
218 //QSet<QPair<QString, QString>> yearsGroupsContainingSubgroup_Set;
219 for(StudentsYear* year : qAsConst(gt.rules.yearsList))
220 for(StudentsGroup* group : qAsConst(year->groupsList))
221 for(StudentsSubgroup* subgroup : qAsConst(group->subgroupsList))
222 if(subgroup->name==subgroupName)
223 yearsGroupsContainingSubgroup_List.append(QPair<QString, QString>(year->name, group->name));
224
225 assert(yearsGroupsContainingSubgroup_List.count()>=1);
226 QString s;
227 if(yearsGroupsContainingSubgroup_List.count()==1)
228 s=tr("This subgroup exists only in year %1, group %2. This means that"
229 " all the related activities and constraints will be removed. Do you want to continue?").arg(yearName).arg(groupName);
230 else{
231 s=tr("This subgroup exists in more places, listed below. It will only be removed from the current year/group,"
232 " and the related activities and constraints will not be removed. Do you want to continue?");
233 s+="\n";
234 for(const QPair<QString, QString>& pair : qAsConst(yearsGroupsContainingSubgroup_List))
235 s+=QString("\n")+pair.first+QString(", ")+pair.second;
236 }
237
238 int t=LongTextMessageBox::mediumConfirmation(this, tr("FET confirmation"), s,
239 tr("Yes"), tr("No"), QString(), 0, 1);
240 if(t==1)
241 return;
242
243 /*if(QMessageBox::warning( this, tr("FET"),
244 tr("Are you sure you want to delete subgroup %1 and all related activities and constraints?").arg(subgroupName),
245 tr("Yes"), tr("No"), 0, 0, 1 ) == 1)
246 return;*/
247
248 bool tmp=gt.rules.removeSubgroup(yearName, groupName, subgroupName);
249 assert(tmp);
250 if(tmp){
251 int q=subgroupsListWidget->currentRow();
252
253 subgroupsListWidget->setCurrentRow(-1);
254 QListWidgetItem* item;
255 item=subgroupsListWidget->takeItem(q);
256 delete item;
257
258 if(q>=subgroupsListWidget->count())
259 q=subgroupsListWidget->count()-1;
260 if(q>=0)
261 subgroupsListWidget->setCurrentRow(q);
262 else
263 subgroupTextEdit->setPlainText(QString(""));
264 }
265
266 /*if(gt.rules.searchStudentsSet(subgroupName)!=nullptr)
267 QMessageBox::information( this, tr("FET"), tr("This subgroup still exists into another group. "
268 "The related activities and constraints were not removed"));*/
269 }
270
purgeSubgroup()271 void SubgroupsForm::purgeSubgroup()
272 {
273 if(yearsListWidget->currentRow()<0){
274 QMessageBox::information(this, tr("FET information"), tr("Invalid selected year"));
275 return;
276 }
277 QString yearName=yearsListWidget->currentItem()->text();
278 int yearIndex=gt.rules.searchYear(yearName);
279 assert(yearIndex>=0);
280
281 if(groupsListWidget->currentRow()<0){
282 QMessageBox::information(this, tr("FET information"), tr("Invalid selected group"));
283 return;
284 }
285 QString groupName=groupsListWidget->currentItem()->text();
286 int groupIndex=gt.rules.searchGroup(yearName, groupName);
287 assert(groupIndex>=0);
288
289 if(subgroupsListWidget->currentRow()<0){
290 QMessageBox::information(this, tr("FET information"), tr("Invalid selected subgroup"));
291 return;
292 }
293
294 QString subgroupName=subgroupsListWidget->currentItem()->text();
295 int subgroupIndex=gt.rules.searchSubgroup(yearName, groupName, subgroupName);
296 assert(subgroupIndex>=0);
297
298 QList<QPair<QString, QString>> yearsGroupsContainingSubgroup_List;
299 //QSet<QPair<QString, QString>> yearsGroupsContainingSubgroup_Set;
300 for(StudentsYear* year : qAsConst(gt.rules.yearsList))
301 for(StudentsGroup* group : qAsConst(year->groupsList))
302 for(StudentsSubgroup* subgroup : qAsConst(group->subgroupsList))
303 if(subgroup->name==subgroupName)
304 yearsGroupsContainingSubgroup_List.append(QPair<QString, QString>(year->name, group->name));
305
306 assert(yearsGroupsContainingSubgroup_List.count()>=1);
307 QString s;
308 if(yearsGroupsContainingSubgroup_List.count()==1)
309 s=tr("This subgroup exists only in year %1, group %2. All the related activities and constraints "
310 "will be removed. Do you want to continue?").arg(yearName).arg(groupName);
311 else{
312 s=tr("This subgroup exists in more places, listed below. It will be removed from all these places."
313 " All the related activities and constraints will be removed. Do you want to continue?");
314 s+="\n";
315 for(const QPair<QString, QString>& pair : qAsConst(yearsGroupsContainingSubgroup_List))
316 s+=QString("\n")+pair.first+QString(", ")+pair.second;
317 }
318
319 int t=LongTextMessageBox::mediumConfirmation(this, tr("FET confirmation"), s,
320 tr("Yes"), tr("No"), QString(), 0, 1);
321 if(t==1)
322 return;
323
324 /*if(QMessageBox::warning( this, tr("FET"),
325 tr("Are you sure you want to delete subgroup %1 and all related activities and constraints?").arg(subgroupName),
326 tr("Yes"), tr("No"), 0, 0, 1 ) == 1)
327 return;*/
328
329 bool tmp=gt.rules.purgeSubgroup(subgroupName);
330 assert(tmp);
331 if(tmp){
332 int q=subgroupsListWidget->currentRow();
333
334 subgroupsListWidget->setCurrentRow(-1);
335 QListWidgetItem* item;
336 item=subgroupsListWidget->takeItem(q);
337 delete item;
338
339 if(q>=subgroupsListWidget->count())
340 q=subgroupsListWidget->count()-1;
341 if(q>=0)
342 subgroupsListWidget->setCurrentRow(q);
343 else
344 subgroupTextEdit->setPlainText(QString(""));
345 }
346
347 /*if(gt.rules.searchStudentsSet(subgroupName)!=nullptr)
348 QMessageBox::information( this, tr("FET"), tr("This subgroup still exists into another group. "
349 "The related activities and constraints were not removed"));*/
350 }
351
yearChanged(const QString & yearName)352 void SubgroupsForm::yearChanged(const QString &yearName)
353 {
354 int yearIndex=gt.rules.searchYear(yearName);
355 if(yearIndex<0){
356 groupsListWidget->clear();
357 subgroupsListWidget->clear();
358 subgroupTextEdit->setPlainText(QString(""));
359 return;
360 }
361 StudentsYear* sty=gt.rules.yearsList.at(yearIndex);
362
363 groupsListWidget->clear();
364 for(int i=0; i<sty->groupsList.size(); i++){
365 StudentsGroup* stg=sty->groupsList[i];
366 groupsListWidget->addItem(stg->name);
367 }
368
369 if(groupsListWidget->count()>0)
370 groupsListWidget->setCurrentRow(0);
371 else{
372 subgroupsListWidget->clear();
373 subgroupTextEdit->setPlainText(QString(""));
374 }
375 }
376
groupChanged(const QString & groupName)377 void SubgroupsForm::groupChanged(const QString &groupName)
378 {
379 QString yearName=yearsListWidget->currentItem()->text();
380 int yearIndex=gt.rules.searchYear(yearName);
381 if(yearIndex<0){
382 return;
383 }
384 StudentsYear* sty=gt.rules.yearsList.at(yearIndex);
385 int groupIndex=gt.rules.searchGroup(yearName, groupName);
386 if(groupIndex<0){
387 subgroupsListWidget->clear();
388 subgroupTextEdit->setPlainText(QString(""));
389 return;
390 }
391
392 StudentsGroup* stg=sty->groupsList.at(groupIndex);
393
394 subgroupsListWidget->clear();
395 for(int i=0; i<stg->subgroupsList.size(); i++){
396 StudentsSubgroup* sts=stg->subgroupsList[i];
397 subgroupsListWidget->addItem(sts->name);
398 }
399
400 if(subgroupsListWidget->count()>0)
401 subgroupsListWidget->setCurrentRow(0);
402 else
403 subgroupTextEdit->setPlainText(QString(""));
404 }
405
subgroupChanged(const QString & subgroupName)406 void SubgroupsForm::subgroupChanged(const QString &subgroupName)
407 {
408 StudentsSet* ss=gt.rules.searchStudentsSet(subgroupName);
409 if(ss==nullptr){
410 subgroupTextEdit->setPlainText(QString(""));
411 return;
412 }
413 StudentsSubgroup* s=(StudentsSubgroup*)ss;
414 subgroupTextEdit->setPlainText(s->getDetailedDescriptionWithConstraints(gt.rules));
415 }
416
moveSubgroupUp()417 void SubgroupsForm::moveSubgroupUp()
418 {
419 if(subgroupsListWidget->count()<=1)
420 return;
421 int i=subgroupsListWidget->currentRow();
422 if(i<0 || i>=subgroupsListWidget->count())
423 return;
424 if(i==0)
425 return;
426
427 QString s1=subgroupsListWidget->item(i)->text();
428 QString s2=subgroupsListWidget->item(i-1)->text();
429
430 assert(yearsListWidget->currentRow()>=0);
431 assert(yearsListWidget->currentRow()<gt.rules.yearsList.count());
432 StudentsYear* sy=gt.rules.yearsList.at(yearsListWidget->currentRow());
433
434 assert(groupsListWidget->currentRow()>=0);
435 assert(groupsListWidget->currentRow()<sy->groupsList.count());
436 StudentsGroup* sg=sy->groupsList.at(groupsListWidget->currentRow());
437
438 StudentsSubgroup* ss1=sg->subgroupsList.at(i);
439 StudentsSubgroup* ss2=sg->subgroupsList.at(i-1);
440
441 gt.rules.internalStructureComputed=false;
442 setRulesModifiedAndOtherThings(>.rules);
443
444 teachers_schedule_ready=false;
445 students_schedule_ready=false;
446 rooms_schedule_ready=false;
447
448 subgroupsListWidget->item(i)->setText(s2);
449 subgroupsListWidget->item(i-1)->setText(s1);
450
451 sg->subgroupsList[i]=ss2;
452 sg->subgroupsList[i-1]=ss1;
453
454 subgroupsListWidget->setCurrentRow(i-1);
455 subgroupChanged(/*i-1*/s1);
456 }
457
moveSubgroupDown()458 void SubgroupsForm::moveSubgroupDown()
459 {
460 if(subgroupsListWidget->count()<=1)
461 return;
462 int i=subgroupsListWidget->currentRow();
463 if(i<0 || i>=subgroupsListWidget->count())
464 return;
465 if(i==subgroupsListWidget->count()-1)
466 return;
467
468 QString s1=subgroupsListWidget->item(i)->text();
469 QString s2=subgroupsListWidget->item(i+1)->text();
470
471 assert(yearsListWidget->currentRow()>=0);
472 assert(yearsListWidget->currentRow()<gt.rules.yearsList.count());
473 StudentsYear* sy=gt.rules.yearsList.at(yearsListWidget->currentRow());
474
475 assert(groupsListWidget->currentRow()>=0);
476 assert(groupsListWidget->currentRow()<sy->groupsList.count());
477 StudentsGroup* sg=sy->groupsList.at(groupsListWidget->currentRow());
478
479 StudentsSubgroup* ss1=sg->subgroupsList.at(i);
480 StudentsSubgroup* ss2=sg->subgroupsList.at(i+1);
481
482 gt.rules.internalStructureComputed=false;
483 setRulesModifiedAndOtherThings(>.rules);
484
485 teachers_schedule_ready=false;
486 students_schedule_ready=false;
487 rooms_schedule_ready=false;
488
489 subgroupsListWidget->item(i)->setText(s2);
490 subgroupsListWidget->item(i+1)->setText(s1);
491
492 sg->subgroupsList[i]=ss2;
493 sg->subgroupsList[i+1]=ss1;
494
495 subgroupsListWidget->setCurrentRow(i+1);
496 subgroupChanged(/*i+1*/s1);
497 }
498
sortSubgroups()499 void SubgroupsForm::sortSubgroups()
500 {
501 if(yearsListWidget->currentRow()<0){
502 QMessageBox::information(this, tr("FET information"), tr("Invalid selected year"));
503 return;
504 }
505 QString yearName=yearsListWidget->currentItem()->text();
506 int yearIndex=gt.rules.searchYear(yearName);
507 assert(yearIndex>=0);
508
509 if(groupsListWidget->currentRow()<0){
510 QMessageBox::information(this, tr("FET information"), tr("Invalid selected group"));
511 return;
512 }
513 QString groupName=groupsListWidget->currentItem()->text();
514 int groupIndex=gt.rules.searchGroup(yearName, groupName);
515 assert(groupIndex>=0);
516
517 gt.rules.sortSubgroupsAlphabetically(yearName, groupName);
518
519 groupChanged(groupName);
520 }
521
modifySubgroup()522 void SubgroupsForm::modifySubgroup()
523 {
524 if(yearsListWidget->currentRow()<0){
525 QMessageBox::information(this, tr("FET information"), tr("Invalid selected year"));
526 return;
527 }
528 QString yearName=yearsListWidget->currentItem()->text();
529 int yearIndex=gt.rules.searchYear(yearName);
530 assert(yearIndex>=0);
531
532 if(groupsListWidget->currentRow()<0){
533 QMessageBox::information(this, tr("FET information"), tr("Invalid selected group"));
534 return;
535 }
536 QString groupName=groupsListWidget->currentItem()->text();
537 int groupIndex=gt.rules.searchGroup(yearName, groupName);
538 assert(groupIndex>=0);
539
540 int q=subgroupsListWidget->currentRow();
541 int valv=subgroupsListWidget->verticalScrollBar()->value();
542 int valh=subgroupsListWidget->horizontalScrollBar()->value();
543
544 if(subgroupsListWidget->currentRow()<0){
545 QMessageBox::information(this, tr("FET information"), tr("Invalid selected subgroup"));
546 return;
547 }
548 QString subgroupName=subgroupsListWidget->currentItem()->text();
549 int subgroupIndex=gt.rules.searchSubgroup(yearName, groupName, subgroupName);
550 assert(subgroupIndex>=0);
551
552 StudentsSet* studentsSet=gt.rules.searchStudentsSet(subgroupName);
553 assert(studentsSet!=nullptr);
554 int numberOfStudents=studentsSet->numberOfStudents;
555
556 ModifyStudentsSubgroupForm form(this, yearName, groupName, subgroupName, numberOfStudents);
557 setParentAndOtherThings(&form, this);
558 form.exec();
559
560 groupChanged(groupName);
561
562 subgroupsListWidget->verticalScrollBar()->setValue(valv);
563 subgroupsListWidget->horizontalScrollBar()->setValue(valh);
564
565 if(q>=subgroupsListWidget->count())
566 q=subgroupsListWidget->count()-1;
567 if(q>=0)
568 subgroupsListWidget->setCurrentRow(q);
569 else
570 subgroupTextEdit->setPlainText(QString(""));
571 }
572
activateStudents()573 void SubgroupsForm::activateStudents()
574 {
575 if(yearsListWidget->currentRow()<0){
576 QMessageBox::information(this, tr("FET information"), tr("Invalid selected year"));
577 return;
578 }
579 QString yearName=yearsListWidget->currentItem()->text();
580 int yearIndex=gt.rules.searchYear(yearName);
581 assert(yearIndex>=0);
582
583 if(groupsListWidget->currentRow()<0){
584 QMessageBox::information(this, tr("FET information"), tr("Invalid selected group"));
585 return;
586 }
587 QString groupName=groupsListWidget->currentItem()->text();
588 int groupIndex=gt.rules.searchGroup(yearName, groupName);
589 assert(groupIndex>=0);
590
591 if(subgroupsListWidget->currentRow()<0){
592 QMessageBox::information(this, tr("FET information"), tr("Invalid selected subgroup"));
593 return;
594 }
595
596 QString subgroupName=subgroupsListWidget->currentItem()->text();
597 int count=gt.rules.activateStudents(subgroupName);
598 QMessageBox::information(this, tr("FET information"), tr("Activated a number of %1 activities").arg(count));
599 }
600
deactivateStudents()601 void SubgroupsForm::deactivateStudents()
602 {
603 if(yearsListWidget->currentRow()<0){
604 QMessageBox::information(this, tr("FET information"), tr("Invalid selected year"));
605 return;
606 }
607 QString yearName=yearsListWidget->currentItem()->text();
608 int yearIndex=gt.rules.searchYear(yearName);
609 assert(yearIndex>=0);
610
611 if(groupsListWidget->currentRow()<0){
612 QMessageBox::information(this, tr("FET information"), tr("Invalid selected group"));
613 return;
614 }
615 QString groupName=groupsListWidget->currentItem()->text();
616 int groupIndex=gt.rules.searchGroup(yearName, groupName);
617 assert(groupIndex>=0);
618
619 if(subgroupsListWidget->currentRow()<0){
620 QMessageBox::information(this, tr("FET information"), tr("Invalid selected subgroup"));
621 return;
622 }
623
624 QString subgroupName=subgroupsListWidget->currentItem()->text();
625 int count=gt.rules.deactivateStudents(subgroupName);
626 QMessageBox::information(this, tr("FET information"), tr("De-activated a number of %1 activities").arg(count));
627 }
628
comments()629 void SubgroupsForm::comments()
630 {
631 int ind=subgroupsListWidget->currentRow();
632 if(ind<0){
633 QMessageBox::information(this, tr("FET information"), tr("Invalid selected subgroup"));
634 return;
635 }
636
637 QString subgroupName=subgroupsListWidget->currentItem()->text();
638
639 StudentsSet* studentsSet=gt.rules.searchStudentsSet(subgroupName);
640 assert(studentsSet!=nullptr);
641
642 QDialog getCommentsDialog(this);
643
644 getCommentsDialog.setWindowTitle(tr("Students subgroup comments"));
645
646 QPushButton* okPB=new QPushButton(tr("OK"));
647 okPB->setDefault(true);
648 QPushButton* cancelPB=new QPushButton(tr("Cancel"));
649
650 connect(okPB, SIGNAL(clicked()), &getCommentsDialog, SLOT(accept()));
651 connect(cancelPB, SIGNAL(clicked()), &getCommentsDialog, SLOT(reject()));
652
653 QHBoxLayout* hl=new QHBoxLayout();
654 hl->addStretch();
655 hl->addWidget(okPB);
656 hl->addWidget(cancelPB);
657
658 QVBoxLayout* vl=new QVBoxLayout();
659
660 QPlainTextEdit* commentsPT=new QPlainTextEdit();
661 commentsPT->setPlainText(studentsSet->comments);
662 commentsPT->selectAll();
663 commentsPT->setFocus();
664
665 vl->addWidget(commentsPT);
666 vl->addLayout(hl);
667
668 getCommentsDialog.setLayout(vl);
669
670 const QString settingsName=QString("StudentsSubgroupCommentsDialog");
671
672 getCommentsDialog.resize(500, 320);
673 centerWidgetOnScreen(&getCommentsDialog);
674 restoreFETDialogGeometry(&getCommentsDialog, settingsName);
675
676 int t=getCommentsDialog.exec();
677 saveFETDialogGeometry(&getCommentsDialog, settingsName);
678
679 if(t==QDialog::Accepted){
680 studentsSet->comments=commentsPT->toPlainText();
681
682 gt.rules.internalStructureComputed=false;
683 setRulesModifiedAndOtherThings(>.rules);
684
685 subgroupChanged(subgroupName);
686 }
687 }
688