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