1 //
2 //
3 // Description: This file is part of FET
4 //
5 //
6 // Author: Liviu Lalescu <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 "studentsset.h"
19 #include "rules.h"
20 #include "timetable.h"
21
22 extern Timetable gt;
23
StudentsSet()24 StudentsSet::StudentsSet()
25 {
26 this->type=STUDENTS_SET;
27 this->numberOfStudents=0;
28 comments=QString("");
29 }
30
~StudentsSet()31 StudentsSet::~StudentsSet()
32 {
33 }
34
StudentsYear()35 StudentsYear::StudentsYear()
36 : StudentsSet()
37 {
38 this->type=STUDENTS_YEAR;
39
40 divisions.clear();
41 separator=QString(" ");
42
43 indexInAugmentedYearsList=-1;
44 }
45
~StudentsYear()46 StudentsYear::~StudentsYear()
47 {
48 }
49
getXmlDescription()50 QString StudentsYear::getXmlDescription()
51 {
52 QString s="";
53 s+="<Year>\n";
54 s+=" <Name>"+protect(this->name)+"</Name>\n";
55 s+=" <Number_of_Students>"+CustomFETString::number(this->numberOfStudents)+"</Number_of_Students>\n";
56 s+=" <Comments>"+protect(comments)+"</Comments>\n";
57
58 s+=" <!-- The information regarding categories, divisions of each category, and separator is only used in the divide year automatically by categories dialog. -->\n";
59 s+=" <Number_of_Categories>"+QString::number(divisions.count())+"</Number_of_Categories>\n";
60 for(const QStringList& tl : qAsConst(divisions)){
61 s+=" <Category>\n";
62 s+=" <Number_of_Divisions>"+QString::number(tl.count())+"</Number_of_Divisions>\n";
63 for(const QString& dn : qAsConst(tl))
64 s+=" <Division>"+protect(dn)+"</Division>\n";
65 s+=" </Category>\n";
66 }
67 s+=" <Separator>"+protect(separator)+"</Separator>\n";
68
69 for(int i=0; i<this->groupsList.size(); i++){
70 StudentsGroup* stg=this->groupsList[i];
71 s+=stg->getXmlDescription();
72 }
73 s+="</Year>\n";
74
75 return s;
76 }
77
getDescription()78 QString StudentsYear::getDescription()
79 {
80 QString s;
81 s+=tr("YN:%1", "Year name").arg(this->name);
82 s+=", ";
83 s+=tr("NoS:%1", "Number of students").arg(this->numberOfStudents);
84
85 QString end=QString("");
86 if(!comments.isEmpty())
87 end=QString(", ")+tr("C: %1", "Comments").arg(comments);
88
89 return s+end;
90 }
91
getDetailedDescription()92 QString StudentsYear::getDetailedDescription()
93 {
94 QString s="";
95 s+=tr("Students set - year");
96 s+="\n";
97 s+=tr("Year name=%1").arg(this->name);
98 s+="\n";
99 s+=tr("Number of students=%1").arg(this->numberOfStudents);
100 s+="\n";
101
102 //Has comments?
103 if(!comments.isEmpty()){
104 s+=tr("Comments=%1").arg(comments);
105 s+="\n";
106 }
107
108 return s;
109 }
110
getDetailedDescriptionWithConstraints(Rules & r)111 QString StudentsYear::getDetailedDescriptionWithConstraints(Rules& r)
112 {
113 QString s=this->getDetailedDescription();
114
115 s+="--------------------------------------------------\n";
116 s+=tr("Time constraints directly related to this students year:");
117 s+="\n";
118 for(int i=0; i<r.timeConstraintsList.size(); i++){
119 TimeConstraint* c=r.timeConstraintsList[i];
120 if(c->isRelatedToStudentsSet(r, this)){
121 s+="\n";
122 s+=c->getDetailedDescription(r);
123 }
124 }
125
126 s+="--------------------------------------------------\n";
127 s+=tr("Space constraints directly related to this students year:");
128 s+="\n";
129 for(int i=0; i<r.spaceConstraintsList.size(); i++){
130 SpaceConstraint* c=r.spaceConstraintsList[i];
131 if(c->isRelatedToStudentsSet(r, this)){
132 s+="\n";
133 s+=c->getDetailedDescription(r);
134 }
135 }
136 s+="--------------------------------------------------\n";
137
138 return s;
139 }
140
141
StudentsGroup()142 StudentsGroup::StudentsGroup()
143 : StudentsSet()
144 {
145 this->type=STUDENTS_GROUP;
146
147 indexInInternalGroupsList=-1;
148 }
149
~StudentsGroup()150 StudentsGroup::~StudentsGroup()
151 {
152 }
153
getXmlDescription()154 QString StudentsGroup::getXmlDescription()
155 {
156 QString s="";
157 s+=" <Group>\n";
158 s+=" <Name>"+protect(this->name)+"</Name>\n";
159 s+=" <Number_of_Students>"+CustomFETString::number(this->numberOfStudents)+"</Number_of_Students>\n";
160 s+=" <Comments>"+protect(comments)+"</Comments>\n";
161 for(int i=0; i<this->subgroupsList.size(); i++){
162 StudentsSubgroup* sts=this->subgroupsList[i];
163 s+=sts->getXmlDescription();
164 }
165 s+=" </Group>\n";
166
167 return s;
168 }
169
getDescription()170 QString StudentsGroup::getDescription()
171 {
172 QString s="";
173 s+=tr("GN:%1", "Group name").arg(this->name);
174 s+=", ";
175 s+=tr("NoS:%1", "Number of students").arg(this->numberOfStudents);
176
177 QString end=QString("");
178 if(!comments.isEmpty())
179 end=QString(", ")+tr("C: %1", "Comments").arg(comments);
180
181 return s+end;
182 }
183
getDetailedDescription()184 QString StudentsGroup::getDetailedDescription()
185 {
186 QString s="";
187 s+=tr("Students set - group");
188 s+="\n";
189 s+=tr("Group name=%1").arg(this->name);
190 s+="\n";
191 s+=tr("Number of students=%1").arg(this->numberOfStudents);
192 s+="\n";
193
194 //Has comments?
195 if(!comments.isEmpty()){
196 s+=tr("Comments=%1").arg(comments);
197 s+="\n";
198 }
199
200 return s;
201 }
202
getDetailedDescriptionWithConstraints(Rules & r)203 QString StudentsGroup::getDetailedDescriptionWithConstraints(Rules& r)
204 {
205 QString s=this->getDetailedDescription();
206
207 s+="--------------------------------------------------\n";
208 s+=tr("Time constraints directly related to this students group:");
209 s+="\n";
210 for(int i=0; i<r.timeConstraintsList.size(); i++){
211 TimeConstraint* c=r.timeConstraintsList[i];
212 if(c->isRelatedToStudentsSet(r, this)){
213 s+="\n";
214 s+=c->getDetailedDescription(r);
215 }
216 }
217
218 s+="--------------------------------------------------\n";
219 s+=tr("Space constraints directly related to this students group:");
220 s+="\n";
221 for(int i=0; i<r.spaceConstraintsList.size(); i++){
222 SpaceConstraint* c=r.spaceConstraintsList[i];
223 if(c->isRelatedToStudentsSet(r, this)){
224 s+="\n";
225 s+=c->getDetailedDescription(r);
226 }
227 }
228 s+="--------------------------------------------------\n";
229
230 return s;
231 }
232
233
StudentsSubgroup()234 StudentsSubgroup::StudentsSubgroup()
235 : StudentsSet()
236 {
237 this->type=STUDENTS_SUBGROUP;
238
239 indexInInternalSubgroupsList=-1;
240 }
241
~StudentsSubgroup()242 StudentsSubgroup::~StudentsSubgroup()
243 {
244 }
245
getXmlDescription()246 QString StudentsSubgroup::getXmlDescription()
247 {
248 QString s="";
249 s+=" <Subgroup>\n";
250 s+=" <Name>"+protect(this->name)+"</Name>\n";
251 s+=" <Number_of_Students>"+CustomFETString::number(this->numberOfStudents)+"</Number_of_Students>\n";
252 s+=" <Comments>"+protect(comments)+"</Comments>\n";
253 s+=" </Subgroup>\n";
254
255 return s;
256 }
257
getDescription()258 QString StudentsSubgroup::getDescription()
259 {
260 QString s="";
261 s+=tr("SgN:%1", "Subgroup name").arg(this->name);
262 s+=", ";
263 s+=tr("NoS:%1", "Number of students").arg(this->numberOfStudents);
264
265 QString end=QString("");
266 if(!comments.isEmpty())
267 end=QString(", ")+tr("C: %1", "Comments").arg(comments);
268
269 return s+end;
270 }
271
getDetailedDescription()272 QString StudentsSubgroup::getDetailedDescription()
273 {
274 QString s="";
275 s+=tr("Students set - subgroup");
276 s+="\n";
277 s+=tr("Subgroup name=%1").arg(this->name);
278 s+="\n";
279 s+=tr("Number of students=%1").arg(this->numberOfStudents);
280 s+="\n";
281
282 //Has comments?
283 if(!comments.isEmpty()){
284 s+=tr("Comments=%1").arg(comments);
285 s+="\n";
286 }
287
288 return s;
289 }
290
getDetailedDescriptionWithConstraints(Rules & r)291 QString StudentsSubgroup::getDetailedDescriptionWithConstraints(Rules& r)
292 {
293 QString s=this->getDetailedDescription();
294
295 s+="--------------------------------------------------\n";
296 s+=tr("Time constraints directly related to this students subgroup:");
297 s+="\n";
298 for(int i=0; i<r.timeConstraintsList.size(); i++){
299 TimeConstraint* c=r.timeConstraintsList[i];
300 if(c->isRelatedToStudentsSet(r, this)){
301 s+="\n";
302 s+=c->getDetailedDescription(r);
303 }
304 }
305
306 s+="--------------------------------------------------\n";
307 s+=tr("Space constraints directly related to this students subgroup:");
308 s+="\n";
309 for(int i=0; i<r.spaceConstraintsList.size(); i++){
310 SpaceConstraint* c=r.spaceConstraintsList[i];
311 if(c->isRelatedToStudentsSet(r, this)){
312 s+="\n";
313 s+=c->getDetailedDescription(r);
314 }
315 }
316 s+="--------------------------------------------------\n";
317
318 return s;
319 }
320
yearsAscending(const StudentsYear * y1,const StudentsYear * y2)321 int yearsAscending(const StudentsYear* y1, const StudentsYear* y2)
322 {
323 //return y1->name < y2->name;
324 //by Rodolfo Ribeiro Gomes
325 return y1->name.localeAwareCompare(y2->name)<0;
326 }
327
groupsAscending(const StudentsGroup * g1,const StudentsGroup * g2)328 int groupsAscending(const StudentsGroup* g1, const StudentsGroup* g2)
329 {
330 //return g1->name < g2->name;
331 //by Rodolfo Ribeiro Gomes
332 return g1->name.localeAwareCompare(g2->name)<0;
333 }
334
subgroupsAscending(const StudentsSubgroup * s1,const StudentsSubgroup * s2)335 int subgroupsAscending(const StudentsSubgroup* s1, const StudentsSubgroup* s2)
336 {
337 //return s1->name < s2->name;
338 //by Rodolfo Ribeiro Gomes
339 return s1->name.localeAwareCompare(s2->name)<0;
340 }
341