1 /*
2  * privacydlg.cpp
3  * Copyright (C) 2006  Remko Troncon
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18  *
19  */
20 
21 #include <QListView>
22 #include <QInputDialog>
23 #include <QMessageBox>
24 
25 #include "privacydlg.h"
26 #include "privacylist.h"
27 #include "privacymanager.h"
28 #include "privacylistmodel.h"
29 
30 // fixme: subscribe on the destroyed() signal of the manager
31 
PrivacyDlg(const QString & account_name,PrivacyManager * manager,QWidget * parent)32 PrivacyDlg::PrivacyDlg(const QString& account_name, PrivacyManager* manager, QWidget* parent) : QDialog(parent), manager_(manager)
33 {
34 	ui_.setupUi(this);
35 	setAttribute(Qt::WA_DeleteOnClose);
36 	setWindowTitle(tr("%1: Privacy Lists").arg(account_name));
37 	setWindowFlags(Qt::Dialog | Qt::WindowTitleHint | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint | Qt::CustomizeWindowHint);
38 
39 	connect(manager_,SIGNAL(listsReceived(const QString&, const QString&, const QStringList&)),SLOT(updateLists(const QString&, const QString&, const QStringList&)));
40 	connect(manager_,SIGNAL(listReceived(const PrivacyList&)),SLOT(refreshList(const PrivacyList&)));
41 	connect(manager_,SIGNAL(listError()),SLOT(list_failed()));
42 	//connect(manager_,SIGNAL(listNamesError()),SLOT(listNamesError()));
43 	//connect(manager_,SIGNAL(listReceiveError()),SLOT(listReceiveError()));
44 
45 	connect(ui_.cb_active,SIGNAL(activated(int)),SLOT(active_selected(int)));
46 	connect(ui_.cb_default,SIGNAL(activated(int)),SLOT(default_selected(int)));
47 	connect(ui_.cb_lists,SIGNAL(activated(int)),SLOT(list_selected(int)));
48 	connect(ui_.cb_lists,SIGNAL(currentIndexChanged(int)),SLOT(list_changed(int)));
49 	connect(manager_,SIGNAL(changeActiveList_success(QString)),SLOT(changeActiveList_succeeded(QString)));
50 	connect(manager_,SIGNAL(changeActiveList_error()),SLOT(change_failed()));
51 	connect(manager_,SIGNAL(changeDefaultList_success(QString)),SLOT(changeDefaultList_succeeded(QString)));
52 	connect(manager_,SIGNAL(changeDefaultList_error()),SLOT(change_failed()));
53 	connect(manager_,SIGNAL(changeList_success(QString)),SLOT(changeList_succeeded(QString)));
54 	connect(manager_,SIGNAL(changeList_error()),SLOT(changeList_failed()));
55 
56 	connect(ui_.pb_newList,SIGNAL(clicked()),SLOT(newList()));
57 	connect(ui_.pb_deleteList,SIGNAL(clicked()),SLOT(removeList()));
58 	connect(ui_.pb_renameList,SIGNAL(clicked()),SLOT(renameList()));
59 
60 	connect(ui_.pb_add,SIGNAL(clicked()),SLOT(addRule()));
61 	connect(ui_.pb_edit,SIGNAL(clicked()),SLOT(editCurrentRule()));
62 	connect(ui_.pb_remove,SIGNAL(clicked()),SLOT(removeCurrentRule()));
63 	connect(ui_.pb_up,SIGNAL(clicked()),SLOT(moveCurrentRuleUp()));
64 	connect(ui_.pb_down,SIGNAL(clicked()),SLOT(moveCurrentRuleDown()));
65 	connect(ui_.pb_apply,SIGNAL(clicked()),SLOT(applyList()));
66 
67 	connect(ui_.buttonBox->button(QDialogButtonBox::Close),SIGNAL(clicked()),SLOT(close()));
68 	setWidgetsEnabled(false);
69 
70 	// Disable all buttons
71 	ui_.pb_deleteList->setEnabled(false);
72 	setEditRuleEnabled(false);
73 	ui_.pb_add->setEnabled(false);
74 	ui_.pb_apply->setEnabled(false);
75 
76 	// FIXME: Temporarily disabling auto-activate
77 	ui_.ck_autoActivate->hide();
78 
79 	manager_->requestListNames();
80 }
81 
setWidgetsEnabled(bool b)82 void PrivacyDlg::setWidgetsEnabled(bool b)
83 {
84 	ui_.gb_settings->setEnabled(b);
85 	ui_.gb_listSettings->setEnabled(b);
86 }
87 
setEditRuleEnabled(bool b)88 void PrivacyDlg::setEditRuleEnabled(bool b)
89 {
90 	ui_.pb_up->setEnabled(b);
91 	ui_.pb_down->setEnabled(b);
92 	ui_.pb_edit->setEnabled(b);
93 	ui_.pb_remove->setEnabled(b);
94 }
95 
addRule()96 void PrivacyDlg::addRule()
97 {
98 	model_.add();
99 }
100 
editCurrentRule()101 void PrivacyDlg::editCurrentRule()
102 {
103 	// Maybe should use MVC setData here
104 	model_.edit(ui_.lv_rules->currentIndex());
105 }
106 
removeCurrentRule()107 void PrivacyDlg::removeCurrentRule()
108 {
109 	if (ui_.lv_rules->currentIndex().isValid()) {
110 		model_.removeRow(ui_.lv_rules->currentIndex().row(),ui_.lv_rules->currentIndex().parent());
111 	}
112 }
113 
moveCurrentRuleUp()114 void PrivacyDlg::moveCurrentRuleUp()
115 {
116 	int row = ui_.lv_rules->currentIndex().row();
117 	if (model_.moveUp(ui_.lv_rules->currentIndex())) {
118 		ui_.lv_rules->setCurrentIndex(model_.index(row-1,0));
119 	}
120 }
121 
moveCurrentRuleDown()122 void PrivacyDlg::moveCurrentRuleDown()
123 {
124 	int row = ui_.lv_rules->currentIndex().row();
125 	if (model_.moveDown(ui_.lv_rules->currentIndex())) {
126 		ui_.lv_rules->setCurrentIndex(model_.index(row+1,0));
127 	}
128 }
129 
applyList()130 void PrivacyDlg::applyList()
131 {
132 	if (!model_.list().isEmpty()) {
133 		setWidgetsEnabled(false);
134 		manager_->changeList(model_.list());
135 		if (newList_)
136 			manager_->requestListNames();
137 	}
138 }
139 
close()140 void PrivacyDlg::close()
141 {
142 	// FIXME: Warn about unsaved changes
143 	done(0);
144 }
145 
updateLists(const QString & defaultList,const QString & activeList,const QStringList & names)146 void PrivacyDlg::updateLists(const QString& defaultList, const QString& activeList, const QStringList& names)
147 {
148 	// Active list
149 	ui_.cb_active->clear();
150 	ui_.cb_active->addItem(tr("<None>"));
151 	ui_.cb_active->addItems(names);
152 	if (!activeList.isEmpty()) {
153 		ui_.cb_active->setCurrentIndex(names.indexOf(activeList)+1);
154 	}
155 	else {
156 		ui_.cb_active->setCurrentIndex(0);
157 	}
158 	previousActive_ = ui_.cb_active->currentIndex();
159 
160 	// Default list
161 	ui_.cb_default->clear();
162 	ui_.cb_default->addItem(tr("<None>"));
163 	ui_.cb_default->addItems(names);
164 	if (!defaultList.isEmpty()) {
165 		ui_.cb_default->setCurrentIndex(names.indexOf(defaultList)+1);
166 	}
167 	else {
168 		ui_.cb_default->setCurrentIndex(0);
169 	}
170 	previousDefault_ = ui_.cb_default->currentIndex();
171 
172 	// All lists
173 	QString previousList = ui_.cb_lists->currentText();
174 	ui_.cb_lists->clear();
175 	ui_.cb_lists->addItems(names);
176 	if (ui_.cb_lists->count() > 0) {
177 		if (!previousList.isEmpty() && ui_.cb_lists->findText(previousList) != -1) {
178 			ui_.cb_lists->setCurrentIndex(ui_.cb_lists->findText(previousList));
179 		}
180 		else {
181 			QString currentList = (activeList.isEmpty() ? activeList : defaultList);
182 			if (!currentList.isEmpty()) {
183 				ui_.cb_lists->setCurrentIndex(names.indexOf(currentList));
184 			}
185 		}
186 		manager_->requestList(ui_.cb_lists->currentText());
187 	}
188 	else {
189 		setWidgetsEnabled(true);
190 	}
191 
192 	ui_.lv_rules->setModel(&model_);
193 	connect(ui_.lv_rules, SIGNAL(doubleClicked(QModelIndex)), SLOT(editCurrentRule()));
194 }
195 
listChanged()196 void PrivacyDlg::listChanged()
197 {
198 	if (model_.list().isEmpty()) {
199 		ui_.cb_lists->removeItem(previousList_);
200 		rememberSettings();
201 	}
202 	setWidgetsEnabled(false);
203 	manager_->requestList(ui_.cb_lists->currentText());
204 }
205 
refreshList(const PrivacyList & list)206 void PrivacyDlg::refreshList(const PrivacyList& list)
207 {
208 	if (list.name() == ui_.cb_lists->currentText()) {
209 		rememberSettings();
210 		model_.setList(list);
211 		setWidgetsEnabled(true);
212 	}
213 }
214 
active_selected(int i)215 void PrivacyDlg::active_selected(int i)
216 {
217 	if (i != previousActive_) {
218 		setWidgetsEnabled(false);
219 		manager_->changeActiveList((i == 0 ? "" : ui_.cb_active->itemText(i)));
220 	}
221 }
222 
default_selected(int i)223 void PrivacyDlg::default_selected(int i)
224 {
225 	if (i != previousDefault_) {
226 		setWidgetsEnabled(false);
227 		manager_->changeDefaultList((i == 0 ? "" : ui_.cb_active->itemText(i)));
228 	}
229 }
230 
list_selected(int i)231 void PrivacyDlg::list_selected(int i)
232 {
233 	if (i != previousList_) {
234 		listChanged();
235 	}
236 }
237 
list_changed(int i)238 void PrivacyDlg::list_changed(int i)
239 {
240 	ui_.pb_deleteList->setEnabled(i != -1);
241 	ui_.pb_add->setEnabled(i != -1);
242 	setEditRuleEnabled(i != -1);
243 	ui_.pb_apply->setEnabled(i != -1);
244 	//setEditRuleEnabled(false);
245 	newList_ = false;
246 }
247 
list_failed()248 void PrivacyDlg::list_failed()
249 {
250 	revertSettings();
251 	setWidgetsEnabled(true);
252 }
253 
changeActiveList_succeeded(QString name)254 void PrivacyDlg::changeActiveList_succeeded(QString name)
255 {
256 	if(!name.isEmpty() && ui_.cb_active->findText(name) == -1) {
257 		ui_.cb_active->addItem(name);
258 		ui_.cb_active->setCurrentIndex(ui_.cb_active->findText(name));
259 	}
260 	change_succeeded();
261 }
262 
changeDefaultList_succeeded(QString name)263 void PrivacyDlg::changeDefaultList_succeeded(QString name)
264 {
265 	if(!name.isEmpty() && ui_.cb_default->findText(name) == -1) {
266 		ui_.cb_default->addItem(name);
267 		ui_.cb_default->setCurrentIndex(ui_.cb_default->findText(name));
268 	}
269 	change_succeeded();
270 }
271 
changeList_succeeded(QString name)272 void PrivacyDlg::changeList_succeeded(QString name)
273 {
274 	if(!name.isEmpty() && ui_.cb_lists->findText(name) == -1) {
275 		ui_.cb_lists->addItem(name);
276 	}
277 	// If we just deleted a list, select the first list
278 	if (model_.list().isEmpty()) {
279 		ui_.cb_lists->setCurrentIndex(0);
280 		listChanged();
281 	}
282 	else {
283 		setWidgetsEnabled(true);
284 	}
285 }
286 
changeList_failed()287 void PrivacyDlg::changeList_failed()
288 {
289 	QMessageBox::critical(0, QObject::tr("Error"), QObject::tr("There was an error changing the list."));
290 	setWidgetsEnabled(true);
291 }
292 
change_succeeded()293 void PrivacyDlg::change_succeeded()
294 {
295 	rememberSettings();
296 	setWidgetsEnabled(true);
297 }
298 
change_failed()299 void PrivacyDlg::change_failed()
300 {
301 	revertSettings();
302 	QMessageBox::critical(0, QObject::tr("Error"), QObject::tr("There was an error processing your request."));
303 	setWidgetsEnabled(true);
304 }
305 
rememberSettings()306 void PrivacyDlg::rememberSettings()
307 {
308 	previousDefault_ = ui_.cb_default->currentIndex();
309 	previousActive_ = ui_.cb_active->currentIndex();
310 	previousList_ = ui_.cb_lists->currentIndex();
311 }
312 
revertSettings()313 void PrivacyDlg::revertSettings()
314 {
315 	ui_.cb_default->setCurrentIndex(previousDefault_);
316 	ui_.cb_active->setCurrentIndex(previousActive_);
317 	ui_.cb_lists->setCurrentIndex(previousList_);
318 }
319 
320 
newList()321 void PrivacyDlg::newList()
322 {
323 	bool done = false;
324 	bool ok = false;
325 	QString name;
326 	while (!done) {
327 		name = QInputDialog::getText(this, tr("New List"), tr("Enter the name of the new list:"), QLineEdit::Normal, "", &ok);
328 		if (!ok) {
329 			done = true;
330 		}
331 		else if (ui_.cb_lists->findText(name) != -1) {
332 			QMessageBox::critical(this, tr("Error"), tr("A list with this name already exists."));
333 		}
334 		else if (!name.isEmpty()) {
335 			done = true;
336 		}
337 	}
338 
339 	if (ok) {
340 		if (ui_.cb_lists->currentIndex() != -1 && model_.list().isEmpty()) {
341 			ui_.cb_lists->removeItem(ui_.cb_lists->currentIndex());
342 		}
343 		ui_.cb_lists->addItem(name);
344 		ui_.cb_lists->setCurrentIndex(ui_.cb_lists->findText(name));
345 		model_.setList(PrivacyList(name));
346 		newList_ = true;
347 		rememberSettings();
348 	}
349 }
350 
removeList()351 void PrivacyDlg::removeList()
352 {
353 	model_.list().clear();
354 	manager_->changeList(model_.list());
355 	manager_->requestListNames();
356 }
357 
renameList()358 void PrivacyDlg::renameList()
359 {
360 	QString newName = QInputDialog::getText(this, tr("Rename List"), tr("Input new name"));
361 	if(newName.isEmpty()) {
362 		return;
363 	}
364 	PrivacyList tmp = model_.list();
365 	model_.list().setName(newName);
366 	tmp.clear();
367 	manager_->changeList(model_.list());
368 	if(ui_.cb_default->currentText() == tmp.name()) {
369 		manager_->changeDefaultList(newName);
370 	}
371 	if(ui_.cb_active->currentText() == tmp.name()) {
372 		manager_->changeActiveList(newName);
373 	}
374 	manager_->changeList(tmp);
375 	manager_->requestListNames();
376 }
377