1 /***************************************************************************
2                           addconstraintmaxdaysbetweenactivitiesform.cpp  -  description
3                              -------------------
4     begin                : 2009
5     copyright            : (C) 2009 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 <QList>
19 
20 #include <QMessageBox>
21 
22 #include "longtextmessagebox.h"
23 
24 #include "addconstraintmaxdaysbetweenactivitiesform.h"
25 #include "spaceconstraint.h"
26 
27 #include <QListWidget>
28 #include <QAbstractItemView>
29 #include <QScrollBar>
30 
AddConstraintMaxDaysBetweenActivitiesForm(QWidget * parent)31 AddConstraintMaxDaysBetweenActivitiesForm::AddConstraintMaxDaysBetweenActivitiesForm(QWidget* parent): QDialog(parent)
32 {
33 	setupUi(this);
34 
35 	addConstraintPushButton->setDefault(true);
36 
37 	allActivitiesListWidget->setSelectionMode(QAbstractItemView::SingleSelection);
38 	selectedActivitiesListWidget->setSelectionMode(QAbstractItemView::SingleSelection);
39 
40 	connect(closePushButton, SIGNAL(clicked()), this, SLOT(close()));
41 	connect(addConstraintPushButton, SIGNAL(clicked()), this, SLOT(addConstraint()));
42 	connect(allActivitiesListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(addActivity()));
43 	connect(addAllActivitiesPushButton, SIGNAL(clicked()), this, SLOT(addAllActivities()));
44 	connect(selectedActivitiesListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(removeActivity()));
45 	connect(clearPushButton, SIGNAL(clicked()), this, SLOT(clear()));
46 
47 	centerWidgetOnScreen(this);
48 	restoreFETDialogGeometry(this);
49 
50 	QSize tmp1=teachersComboBox->minimumSizeHint();
51 	Q_UNUSED(tmp1);
52 	QSize tmp2=studentsComboBox->minimumSizeHint();
53 	Q_UNUSED(tmp2);
54 	QSize tmp3=subjectsComboBox->minimumSizeHint();
55 	Q_UNUSED(tmp3);
56 	QSize tmp4=activityTagsComboBox->minimumSizeHint();
57 	Q_UNUSED(tmp4);
58 
59 	if(gt.rules.mode!=MORNINGS_AFTERNOONS){
60 		maxDaysSpinBox->setMinimum(0);
61 		maxDaysSpinBox->setValue(gt.rules.nDaysPerWeek-1);
62 		maxDaysSpinBox->setMaximum(gt.rules.nDaysPerWeek-1);
63 	}
64 	else{
65 		maxDaysSpinBox->setMinimum(0);
66 		maxDaysSpinBox->setValue(gt.rules.nDaysPerWeek/2-1);
67 		maxDaysSpinBox->setMaximum(gt.rules.nDaysPerWeek/2-1);
68 	}
69 
70 	teachersComboBox->addItem("");
71 	for(int i=0; i<gt.rules.teachersList.size(); i++){
72 		Teacher* tch=gt.rules.teachersList[i];
73 		teachersComboBox->addItem(tch->name);
74 	}
75 	teachersComboBox->setCurrentIndex(0);
76 
77 	subjectsComboBox->addItem("");
78 	for(int i=0; i<gt.rules.subjectsList.size(); i++){
79 		Subject* sb=gt.rules.subjectsList[i];
80 		subjectsComboBox->addItem(sb->name);
81 	}
82 	subjectsComboBox->setCurrentIndex(0);
83 
84 	activityTagsComboBox->addItem("");
85 	for(int i=0; i<gt.rules.activityTagsList.size(); i++){
86 		ActivityTag* st=gt.rules.activityTagsList[i];
87 		activityTagsComboBox->addItem(st->name);
88 	}
89 	activityTagsComboBox->setCurrentIndex(0);
90 
91 	populateStudentsComboBox(studentsComboBox, QString(""), true);
92 	studentsComboBox->setCurrentIndex(0);
93 
94 	selectedActivitiesListWidget->clear();
95 	this->selectedActivitiesList.clear();
96 
97 	filterChanged();
98 
99 	connect(teachersComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(filterChanged()));
100 	connect(studentsComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(filterChanged()));
101 	connect(subjectsComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(filterChanged()));
102 	connect(activityTagsComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(filterChanged()));
103 }
104 
~AddConstraintMaxDaysBetweenActivitiesForm()105 AddConstraintMaxDaysBetweenActivitiesForm::~AddConstraintMaxDaysBetweenActivitiesForm()
106 {
107 	saveFETDialogGeometry(this);
108 }
109 
filterOk(Activity * act)110 bool AddConstraintMaxDaysBetweenActivitiesForm::filterOk(Activity* act)
111 {
112 	QString tn=teachersComboBox->currentText();
113 	QString stn=studentsComboBox->currentText();
114 	QString sbn=subjectsComboBox->currentText();
115 	QString atn=activityTagsComboBox->currentText();
116 	int ok=true;
117 
118 	//teacher
119 	if(tn!=""){
120 		bool ok2=false;
121 		for(QStringList::const_iterator it=act->teachersNames.constBegin(); it!=act->teachersNames.constEnd(); it++)
122 			if(*it == tn){
123 				ok2=true;
124 				break;
125 			}
126 		if(!ok2)
127 			ok=false;
128 	}
129 
130 	//subject
131 	if(sbn!="" && sbn!=act->subjectName)
132 		ok=false;
133 
134 	//activity tag
135 	if(atn!="" && !act->activityTagsNames.contains(atn))
136 		ok=false;
137 
138 	//students
139 	if(stn!=""){
140 		bool ok2=false;
141 		for(QStringList::const_iterator it=act->studentsNames.constBegin(); it!=act->studentsNames.constEnd(); it++)
142 			if(*it == stn){
143 				ok2=true;
144 				break;
145 			}
146 		if(!ok2)
147 			ok=false;
148 	}
149 
150 	return ok;
151 }
152 
filterChanged()153 void AddConstraintMaxDaysBetweenActivitiesForm::filterChanged()
154 {
155 	allActivitiesListWidget->clear();
156 
157 	this->activitiesList.clear();
158 
159 	for(int i=0; i<gt.rules.activitiesList.size(); i++){
160 		Activity* ac=gt.rules.activitiesList[i];
161 		if(filterOk(ac)){
162 			allActivitiesListWidget->addItem(ac->getDescription(gt.rules));
163 			this->activitiesList.append(ac->id);
164 		}
165 	}
166 
167 	int q=allActivitiesListWidget->verticalScrollBar()->minimum();
168 	allActivitiesListWidget->verticalScrollBar()->setValue(q);
169 }
170 
addConstraint()171 void AddConstraintMaxDaysBetweenActivitiesForm::addConstraint()
172 {
173 	TimeConstraint *ctr=nullptr;
174 
175 	double weight;
176 	QString tmp=weightLineEdit->text();
177 	weight_sscanf(tmp, "%lf", &weight);
178 	if(weight<0.0 || weight>100){
179 		QMessageBox::warning(this, tr("FET information"),
180 			tr("Invalid weight (percentage)"));
181 		return;
182 	}
183 
184 	if(this->selectedActivitiesList.count()==0){
185 		QMessageBox::warning(this, tr("FET information"),
186 			tr("Empty list of selected activities"));
187 		return;
188 	}
189 	if(this->selectedActivitiesList.count()==1){
190 		QMessageBox::warning(this, tr("FET information"),
191 			tr("Only one selected activity"));
192 		return;
193 	}
194 
195 	QList<int> ids;
196 	QList<int>::const_iterator it;
197 	for(it=this->selectedActivitiesList.constBegin(); it!=this->selectedActivitiesList.constEnd(); it++)
198 		ids.append(*it);
199 
200 	ctr=new ConstraintMaxDaysBetweenActivities(weight, this->selectedActivitiesList.count(), ids, maxDaysSpinBox->value());
201 
202 	bool tmp2=gt.rules.addTimeConstraint(ctr);
203 
204 	if(tmp2){
205 		QString s=tr("Constraint added:");
206 		s+="\n\n";
207 		s+=ctr->getDetailedDescription(gt.rules);
208 		LongTextMessageBox::information(this, tr("FET information"), s);
209 	}
210 	else{
211 		QMessageBox::warning(this, tr("FET information"),
212 			tr("Constraint NOT added - it must be a duplicate"));
213 		delete ctr;
214 	}
215 }
216 
addActivity()217 void AddConstraintMaxDaysBetweenActivitiesForm::addActivity()
218 {
219 	if(allActivitiesListWidget->currentRow()<0)
220 		return;
221 	int tmp=allActivitiesListWidget->currentRow();
222 	int _id=this->activitiesList.at(tmp);
223 
224 	QString actName=allActivitiesListWidget->currentItem()->text();
225 	assert(actName!="");
226 
227 	//duplicate?
228 	if(this->selectedActivitiesList.contains(_id))
229 		return;
230 
231 	selectedActivitiesListWidget->addItem(actName);
232 	selectedActivitiesListWidget->setCurrentRow(selectedActivitiesListWidget->count()-1);
233 
234 	this->selectedActivitiesList.append(_id);
235 }
236 
addAllActivities()237 void AddConstraintMaxDaysBetweenActivitiesForm::addAllActivities()
238 {
239 	for(int tmp=0; tmp<allActivitiesListWidget->count(); tmp++){
240 		int _id=this->activitiesList.at(tmp);
241 
242 		QString actName=allActivitiesListWidget->item(tmp)->text();
243 		assert(actName!="");
244 
245 		if(this->selectedActivitiesList.contains(_id))
246 			continue;
247 
248 		selectedActivitiesListWidget->addItem(actName);
249 		this->selectedActivitiesList.append(_id);
250 	}
251 
252 	selectedActivitiesListWidget->setCurrentRow(selectedActivitiesListWidget->count()-1);
253 }
254 
removeActivity()255 void AddConstraintMaxDaysBetweenActivitiesForm::removeActivity()
256 {
257 	if(selectedActivitiesListWidget->currentRow()<0 || selectedActivitiesListWidget->count()<=0)
258 		return;
259 	int tmp=selectedActivitiesListWidget->currentRow();
260 
261 	this->selectedActivitiesList.removeAt(tmp);
262 
263 	selectedActivitiesListWidget->setCurrentRow(-1);
264 	QListWidgetItem* item=selectedActivitiesListWidget->takeItem(tmp);
265 	delete item;
266 	if(tmp<selectedActivitiesListWidget->count())
267 		selectedActivitiesListWidget->setCurrentRow(tmp);
268 	else
269 		selectedActivitiesListWidget->setCurrentRow(selectedActivitiesListWidget->count()-1);
270 }
271 
clear()272 void AddConstraintMaxDaysBetweenActivitiesForm::clear()
273 {
274 	selectedActivitiesListWidget->clear();
275 	selectedActivitiesList.clear();
276 }
277