1 /***************************************************************************
2                           modifyconstraintactivitypreferredroomform.cpp  -  description
3                              -------------------
4     begin                : 13 Feb 2005
5     copyright            : (C) 2005 by Liviu Lalescu
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 "modifyconstraintactivitypreferredroomform.h"
21 #include "spaceconstraint.h"
22 
23 #include "lockunlock.h"
24 
25 #include "longtextmessagebox.h"
26 
ModifyConstraintActivityPreferredRoomForm(QWidget * parent,ConstraintActivityPreferredRoom * ctr)27 ModifyConstraintActivityPreferredRoomForm::ModifyConstraintActivityPreferredRoomForm(QWidget* parent, ConstraintActivityPreferredRoom* ctr): QDialog(parent)
28 {
29 	setupUi(this);
30 
31 	okPushButton->setDefault(true);
32 
33 	connect(cancelPushButton, SIGNAL(clicked()), this, SLOT(cancel()));
34 	connect(okPushButton, SIGNAL(clicked()), this, SLOT(ok()));
35 	connect(helpPushButton, SIGNAL(clicked()), this, SLOT(help()));
36 
37 	connect(selectedRealRoomsListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(removeRealRoom()));
38 	connect(clearPushButton, SIGNAL(clicked()), this, SLOT(clearRealRooms()));
39 	connect(allRealRoomsListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(addRealRoom()));
40 
41 	centerWidgetOnScreen(this);
42 	restoreFETDialogGeometry(this);
43 
44 	QSize tmp5=roomsComboBox->minimumSizeHint();
45 	Q_UNUSED(tmp5);
46 	QSize tmp6=activitiesComboBox->minimumSizeHint();
47 	Q_UNUSED(tmp6);
48 
49 	activitiesComboBox->setMaximumWidth(maxRecommendedWidth(this));
50 
51 	this->_ctr=ctr;
52 
53 	weightLineEdit->setText(CustomFETString::number(ctr->weightPercentage));
54 
55 	permLockedCheckBox->setChecked(this->_ctr->permanentlyLocked);
56 
57 	updateActivitiesComboBox();
58 	updateRoomsComboBox();
59 
60 	allRealRoomsListWidget->clear();
61 	for(Room* rm : qAsConst(gt.rules.roomsList))
62 		if(rm->isVirtual==false)
63 			allRealRoomsListWidget->addItem(rm->name);
64 	allRealRoomsListWidget->setCurrentRow(0);
65 
66 	selectedRealRoomsListWidget->clear();
67 	for(const QString& rrn : qAsConst(_ctr->preferredRealRoomsNames))
68 		selectedRealRoomsListWidget->addItem(rrn);
69 	selectedRealRoomsListWidget->setCurrentRow(0);
70 }
71 
~ModifyConstraintActivityPreferredRoomForm()72 ModifyConstraintActivityPreferredRoomForm::~ModifyConstraintActivityPreferredRoomForm()
73 {
74 	saveFETDialogGeometry(this);
75 }
76 
updateActivitiesComboBox()77 void ModifyConstraintActivityPreferredRoomForm::updateActivitiesComboBox()
78 {
79 	int i=0, j=-1;
80 	activitiesComboBox->clear();
81 	for(int k=0; k<gt.rules.activitiesList.size(); k++){
82 		Activity* act=gt.rules.activitiesList[k];
83 		activitiesComboBox->addItem(act->getDescription(gt.rules));
84 		if(act->id==this->_ctr->activityId)
85 			j=i;
86 		i++;
87 	}
88 	assert(j>=0);
89 	activitiesComboBox->setCurrentIndex(j);
90 }
91 
updateRoomsComboBox()92 void ModifyConstraintActivityPreferredRoomForm::updateRoomsComboBox()
93 {
94 	int i=0, j=-1;
95 	roomsComboBox->clear();
96 	for(int k=0; k<gt.rules.roomsList.size(); k++){
97 		Room* rm=gt.rules.roomsList[k];
98 		roomsComboBox->addItem(rm->name);
99 		if(rm->name==this->_ctr->roomName)
100 			j=i;
101 		i++;
102 	}
103 	assert(j>=0);
104 	roomsComboBox->setCurrentIndex(j);
105 }
106 
removeRealRoom()107 void ModifyConstraintActivityPreferredRoomForm::removeRealRoom()
108 {
109 	int ind=selectedRealRoomsListWidget->currentRow();
110 	if(ind<0 || ind>=selectedRealRoomsListWidget->count()){
111 		QMessageBox::information(this, tr("FET information"), tr("Invalid selected real room."));
112 		return;
113 	}
114 
115 	QListWidgetItem* item=selectedRealRoomsListWidget->takeItem(ind);
116 	delete item;
117 
118 	if(ind>=selectedRealRoomsListWidget->count())
119 		ind=selectedRealRoomsListWidget->count()-1;
120 	selectedRealRoomsListWidget->setCurrentRow(ind);
121 }
122 
clearRealRooms()123 void ModifyConstraintActivityPreferredRoomForm::clearRealRooms()
124 {
125 	selectedRealRoomsListWidget->clear();
126 }
127 
addRealRoom()128 void ModifyConstraintActivityPreferredRoomForm::addRealRoom()
129 {
130 	int ind=allRealRoomsListWidget->currentRow();
131 	if(ind<0 || ind>=allRealRoomsListWidget->count()){
132 		QMessageBox::information(this, tr("FET information"), tr("Invalid selected real room."));
133 		return;
134 	}
135 
136 	bool exists=false;
137 	for(int i=0; i<selectedRealRoomsListWidget->count(); i++)
138 		if(selectedRealRoomsListWidget->item(i)->text()==allRealRoomsListWidget->item(ind)->text()){
139 			exists=true;
140 			break;
141 		}
142 
143 	if(!exists){
144 		selectedRealRoomsListWidget->addItem(allRealRoomsListWidget->item(ind)->text());
145 		selectedRealRoomsListWidget->setCurrentRow(selectedRealRoomsListWidget->count()-1);
146 	}
147 }
148 
cancel()149 void ModifyConstraintActivityPreferredRoomForm::cancel()
150 {
151 	this->close();
152 }
153 
ok()154 void ModifyConstraintActivityPreferredRoomForm::ok()
155 {
156 	double weight;
157 	QString tmp=weightLineEdit->text();
158 	weight_sscanf(tmp, "%lf", &weight);
159 	if(weight<0.0 || weight>100){
160 		QMessageBox::warning(this, tr("FET information"),
161 			tr("Invalid weight"));
162 		return;
163 	}
164 
165 	int i=activitiesComboBox->currentIndex();
166 	if(i<0 || activitiesComboBox->count()<=0){
167 		QMessageBox::warning(this, tr("FET information"),
168 			tr("Invalid activity"));
169 		return;
170 	}
171 	Activity* act=gt.rules.activitiesList.at(i);
172 
173 	i=roomsComboBox->currentIndex();
174 	if(i<0 || roomsComboBox->count()<=0){
175 		QMessageBox::warning(this, tr("FET information"),
176 			tr("Invalid room"));
177 		return;
178 	}
179 	QString room=roomsComboBox->currentText();
180 
181 	int ri=gt.rules.searchRoom(room);
182 	assert(ri>=0);
183 	Room* rm=gt.rules.roomsList.at(ri);
184 
185 	if(rm->isVirtual==false){
186 		if(selectedRealRoomsListWidget->count()>0){
187 			QMessageBox::warning(this, tr("FET information"), tr("The preferred room of the activity is a real room, not a virtual one."
188 			 " This implies that the selected real rooms list should be empty."));
189 			return;
190 		}
191 	}
192 	else{
193 		if(selectedRealRoomsListWidget->count()>0 && weight<100.0){
194 			QMessageBox::warning(this, tr("FET information"), tr("If the preferred room is virtual and the list of real rooms is not empty,"
195 			 " the weight percentage must be exactly 100%."));
196 			return;
197 		}
198 
199 		if(selectedRealRoomsListWidget->count()>0 && rm->realRoomsSetsList.count()!=selectedRealRoomsListWidget->count()){
200 			QMessageBox::warning(this, tr("FET information"), tr("The preferred room of the activity is a virtual room."
201 			 " This implies that the number of selected real rooms in the list should either be zero or equal to the"
202 			 " number of sets of real rooms of the preferred virtual room, which is %1.").arg(rm->realRoomsSetsList.count()));
203 			return;
204 		}
205 
206 		QSet<QString> rrs;
207 		for(const QStringList& tl : qAsConst(rm->realRoomsSetsList))
208 			for(const QString& s : qAsConst(tl))
209 				if(!rrs.contains(s))
210 					rrs.insert(s);
211 
212 		QStringList incorrectList;
213 		for(int i=0; i<selectedRealRoomsListWidget->count(); i++){
214 			bool found=false;
215 			QString rrn=selectedRealRoomsListWidget->item(i)->text();
216 			if(rrs.contains(rrn))
217 				found=true;
218 
219 			if(!found)
220 				incorrectList.append(rrn);
221 		}
222 		if(!incorrectList.isEmpty()){
223 			switch(LongTextMessageBox::confirmation(this, tr("FET information"), tr("The selected real rooms: %1 are not found in the sets of sets of real rooms of the"
224 			 " selected preferred virtual room. This is probably wrong. Are you sure you want to add this constraint?").arg(incorrectList.join(", ")),
225 			 tr("Yes"), tr("No"), 0, 0, 1)){
226 			case 0:
227 				break;
228 			case 1:
229 				return;
230 			}
231 		}
232 	}
233 
234 	QStringList lst;
235 	for(int i=0; i<selectedRealRoomsListWidget->count(); i++)
236 		lst.append(selectedRealRoomsListWidget->item(i)->text());
237 
238 	this->_ctr->weightPercentage=weight;
239 	this->_ctr->roomName=room;
240 
241 	if(_ctr->activityId!=act->id){
242 		int oldId=_ctr->activityId;
243 		int newId=act->id;
244 
245 		QSet<ConstraintActivityPreferredRoom*> cs=gt.rules.aprHash.value(oldId, QSet<ConstraintActivityPreferredRoom*>());
246 		assert(cs.contains(_ctr));
247 		cs.remove(_ctr);
248 		gt.rules.aprHash.insert(oldId, cs);
249 
250 		cs=gt.rules.aprHash.value(newId, QSet<ConstraintActivityPreferredRoom*>());
251 		assert(!cs.contains(_ctr));
252 		cs.insert(_ctr);
253 		gt.rules.aprHash.insert(newId, cs);
254 
255 		this->_ctr->activityId=act->id;
256 	}
257 
258 	this->_ctr->permanentlyLocked=permLockedCheckBox->isChecked();
259 
260 	_ctr->preferredRealRoomsNames=lst;
261 
262 	gt.rules.internalStructureComputed=false;
263 	setRulesModifiedAndOtherThings(&gt.rules);
264 
265 	LockUnlock::computeLockedUnlockedActivitiesOnlySpace();
266 	LockUnlock::increaseCommunicationSpinBox();
267 
268 	this->close();
269 }
270 
help()271 void ModifyConstraintActivityPreferredRoomForm::help()
272 {
273 	QString s;
274 
275 	s+=tr("A room can be real (the simplest and the most used scenario) or virtual. You can read more about this in the rooms dialog, by clicking the Help button there.");
276 	s+="\n\n";
277 	s+=tr("If the preferred room selected in the combo box is real, the list of selected real rooms must remain empty.");
278 	s+="\n\n";
279 	s+=tr("If the preferred room selected in the combo box is virtual, you can select also the list of real rooms to be allocated to the "
280 	 "selected activity (if the preferred room selected in the combo box is virtual and the list of selected real rooms is not empty, the "
281 	 "weight of the constraint must be 100.0%).");
282 
283 	LongTextMessageBox::largeInformation(this, tr("FET help"), s);
284 }
285