1 /*
2  * bookmarkmanagedlg.cpp - manage groupchat room bookmarks
3  * Copyright (C) 2008  Michail Pishchagin
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 "bookmarkmanagedlg.h"
22 
23 #include <QStandardItemModel>
24 #include <QPushButton>
25 #include <QAction>
26 #include <QFile>
27 #include <QMessageBox>
28 
29 #include "bookmarkmanager.h"
30 #include "psiaccount.h"
31 #include "fileutil.h"
32 #include "iconset.h"
33 
BookmarkManageDlg(PsiAccount * account)34 BookmarkManageDlg::BookmarkManageDlg(PsiAccount* account)
35 	: QDialog()
36 	, account_(account)
37 	, model_(0)
38 {
39 	setAttribute(Qt::WA_DeleteOnClose, true);
40 	setWindowFlags(Qt::Dialog | Qt::WindowTitleHint | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint | Qt::CustomizeWindowHint);
41 	ui_.setupUi(this);
42 	account_->dialogRegister(this);
43 
44 	QAction* removeBookmarkAction = new QAction(this);
45 	connect(removeBookmarkAction, SIGNAL(triggered()), SLOT(removeBookmark()));
46 	removeBookmarkAction->setShortcuts(QKeySequence::Delete);
47 	ui_.listView->addAction(removeBookmarkAction);
48 
49 	ui_.autoJoin->addItems(ConferenceBookmark::joinTypeNames());
50 
51 	ui_.pb_import->setIcon(IconsetFactory::icon("psi/import").icon());
52 	ui_.pb_export->setIcon(IconsetFactory::icon("psi/export").icon());
53 	connect(ui_.pb_import, SIGNAL(clicked()), SLOT(importBookmarks()));
54 	connect(ui_.pb_export, SIGNAL(clicked()), SLOT(exportBookmarks()));
55 
56 	addButton_    = ui_.bookmarkButtonBox->addButton(tr("&Add"),    QDialogButtonBox::ActionRole);
57 	removeButton_ = ui_.bookmarkButtonBox->addButton(tr("&Remove"), QDialogButtonBox::DestructiveRole);
58 	joinButton_   = ui_.bookmarkButtonBox->addButton(tr("&Join"),   QDialogButtonBox::ActionRole);
59 	connect(addButton_, SIGNAL(clicked()), SLOT(addBookmark()));
60 	connect(removeButton_, SIGNAL(clicked()), SLOT(removeBookmark()));
61 	connect(joinButton_, SIGNAL(clicked()), SLOT(joinCurrentRoom()));
62 
63 	model_ = new QStandardItemModel(this);
64 	ui_.listView->setModel(model_);
65 	connect(ui_.listView->itemDelegate(), SIGNAL(closeEditor(QWidget*, QAbstractItemDelegate::EndEditHint)), SLOT(closeEditor(QWidget*, QAbstractItemDelegate::EndEditHint)));
66 	connect(ui_.listView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), SLOT(selectionChanged(const QItemSelection&, const QItemSelection&)));
67 
68 	connect(ui_.host, SIGNAL(textEdited(const QString&)), SLOT(updateCurrentItem()));
69 	connect(ui_.room, SIGNAL(textEdited(const QString&)), SLOT(updateCurrentItem()));
70 	connect(ui_.nickname, SIGNAL(textEdited(const QString&)), SLOT(updateCurrentItem()));
71 	connect(ui_.password, SIGNAL(textEdited(const QString&)), SLOT(updateCurrentItem()));
72 	connect(ui_.autoJoin, SIGNAL(currentIndexChanged(int)), SLOT(updateCurrentItem()));
73 
74 	loadBookmarks();
75 
76 	QItemSelection dummy;
77 	selectionChanged(dummy, dummy);
78 }
79 
~BookmarkManageDlg()80 BookmarkManageDlg::~BookmarkManageDlg()
81 {
82 	account_->dialogUnregister(this);
83 }
84 
reject()85 void BookmarkManageDlg::reject()
86 {
87 	QDialog::reject();
88 }
89 
accept()90 void BookmarkManageDlg::accept()
91 {
92 	QStandardItem* item = model_->item(ui_.listView->currentIndex().row());
93 	if(item && item->data(Qt::DisplayRole).toString().isEmpty())
94 		item->setData(QVariant(item->data(JidRole)), Qt::DisplayRole);
95 
96 	if (account_->checkConnected(this)) {
97 		saveBookmarks();
98 		QDialog::accept();
99 	}
100 }
101 
loadBookmarks()102 void BookmarkManageDlg::loadBookmarks()
103 {
104 	model_->clear();
105 
106 	foreach(ConferenceBookmark c, account_->bookmarkManager()->conferences()) {
107 		QStandardItem* item = new QStandardItem(c.name());
108 		item->setData(QVariant(c.jid().full()), JidRole);
109 		item->setData(QVariant(c.autoJoin()),   AutoJoinRole);
110 		item->setData(QVariant(c.nick()),       NickRole);
111 		item->setData(QVariant(c.password()),   PasswordRole);
112 		appendItem(item);
113 	}
114 }
115 
bookmarkFor(const QModelIndex & index) const116 ConferenceBookmark BookmarkManageDlg::bookmarkFor(const QModelIndex& index) const
117 {
118 	return ConferenceBookmark(index.data(Qt::DisplayRole).toString(),
119 	                          index.data(JidRole).toString(),
120 							  (ConferenceBookmark::JoinType)index.data(AutoJoinRole).toInt(),
121 	                          index.data(NickRole).toString(),
122 	                          index.data(PasswordRole).toString());
123 }
124 
saveBookmarks()125 void BookmarkManageDlg::saveBookmarks()
126 {
127 	QList<ConferenceBookmark> conferences;
128 	for (int row = 0; row < model_->rowCount(); ++row) {
129 		QModelIndex index = model_->index(row, 0, QModelIndex());
130 		conferences += bookmarkFor(index);
131 	}
132 
133 	account_->bookmarkManager()->setBookmarks(conferences);
134 }
135 
addBookmark()136 void BookmarkManageDlg::addBookmark()
137 {
138 	QStandardItem* item = new QStandardItem(tr("Unnamed"));
139 	appendItem(item);
140 	ui_.listView->reset(); // ensure that open editors won't get in our way
141 	ui_.listView->setCurrentIndex(item->index());
142 	ui_.listView->edit(item->index());
143 }
144 
removeBookmark()145 void BookmarkManageDlg::removeBookmark()
146 {
147 	model_->removeRow(currentIndex().row());
148 }
149 
closeEditor(QWidget * editor,QAbstractItemDelegate::EndEditHint hint)150 void BookmarkManageDlg::closeEditor(QWidget* editor, QAbstractItemDelegate::EndEditHint hint)
151 {
152 	Q_UNUSED(editor);
153 
154 	if (hint == QAbstractItemDelegate::SubmitModelCache) {
155 		QList<QLineEdit*> lineEdits;
156 		lineEdits << ui_.host << ui_.room << ui_.nickname;
157 		foreach(QLineEdit* lineEdit, lineEdits) {
158 			if (lineEdit->text().isEmpty()) {
159 				lineEdit->setFocus();
160 				break;
161 			}
162 		}
163 	}
164 }
165 
selectionChanged(const QItemSelection & selected,const QItemSelection & deselected)166 void BookmarkManageDlg::selectionChanged(const QItemSelection& selected, const QItemSelection& deselected)
167 {
168 	QModelIndex current;
169 	if (!selected.indexes().isEmpty())
170 		current = selected.indexes().first();
171 
172 	if(!deselected.isEmpty()) {
173 		QStandardItem* item = model_->item(deselected.indexes().first().row());
174 		if(item && item->data(Qt::DisplayRole).toString().isEmpty())
175 			item->setData(QVariant(item->data(JidRole)), Qt::DisplayRole);
176 	}
177 
178 	XMPP::Jid jid = XMPP::Jid(current.data(JidRole).toString());
179 	ui_.host->setText(jid.domain());
180 	ui_.room->setText(jid.node());
181 	ui_.nickname->setText(current.data(NickRole).toString());
182 	ui_.password->setText(current.data(PasswordRole).toString());
183 	ui_.autoJoin->setCurrentIndex(current.data(AutoJoinRole).toInt());
184 	QList<QWidget*> editors;
185 	editors << ui_.host << ui_.room << ui_.nickname << ui_.password << ui_.autoJoin;
186 	foreach(QWidget* w, editors) {
187 		w->setEnabled(current.isValid());
188 	}
189 
190 	removeButton_->setEnabled(current.isValid());
191 	updateCurrentItem();
192 }
193 
jid() const194 XMPP::Jid BookmarkManageDlg::jid() const
195 {
196 	return XMPP::Jid(ui_.room->text(), ui_.host->text());
197 }
198 
updateCurrentItem()199 void BookmarkManageDlg::updateCurrentItem()
200 {
201 	joinButton_->setEnabled(!jid().domain().isEmpty() && !jid().node().isEmpty() && !ui_.nickname->text().isEmpty());
202 
203 	QStandardItem* item = model_->item(currentIndex().row());
204 	if (item) {
205 		item->setData(QVariant(jid().full()),              JidRole);
206 		item->setData(QVariant(ui_.autoJoin->currentIndex()), AutoJoinRole);
207 		item->setData(QVariant(ui_.nickname->text()),      NickRole);
208 		item->setData(QVariant(ui_.password->text()),      PasswordRole);
209 	}
210 }
211 
currentIndex() const212 QModelIndex BookmarkManageDlg::currentIndex() const
213 {
214 	if (!ui_.listView->selectionModel()->selectedIndexes().isEmpty())
215 		return ui_.listView->selectionModel()->selectedIndexes().first();
216 	return QModelIndex();
217 }
218 
joinCurrentRoom()219 void BookmarkManageDlg::joinCurrentRoom()
220 {
221 	account_->actionJoin(bookmarkFor(currentIndex()), true);
222 }
223 
appendItem(QStandardItem * item)224 void BookmarkManageDlg::appendItem(QStandardItem* item)
225 {
226 	item->setDragEnabled(true);
227 	item->setDropEnabled(false);
228 	model_->invisibleRootItem()->appendRow(item);
229 }
230 
importBookmarks()231 void BookmarkManageDlg::importBookmarks()
232 {
233 	QString fileName = FileUtil::getOpenFileName(this, tr("Import bookmarks"));
234 	if(fileName.isEmpty())
235 		return;
236 
237 	QFile file(fileName);
238 	if(file.open(QIODevice::ReadOnly | QIODevice::Text)) {
239 		QDomDocument doc;
240 		QString error;
241 		if(doc.setContent(&file, &error)) {
242 			QDomElement root = doc.firstChildElement("bookmarks");
243 			if(root.isNull())
244 				return;
245 			QDomElement elem = root.firstChildElement("conference");
246 			while(!elem.isNull()) {
247 				ConferenceBookmark c(elem);
248 
249 				QStandardItem* item = new QStandardItem(c.name());
250 				item->setData(QVariant(c.jid().full()), JidRole);
251 				item->setData(QVariant(c.autoJoin()),   AutoJoinRole);
252 				item->setData(QVariant(c.nick()),       NickRole);
253 				item->setData(QVariant(c.password()),   PasswordRole);
254 				appendItem(item);
255 
256 				elem = elem.nextSiblingElement("conference");
257 			}
258 		}
259 		else {
260 			QMessageBox::warning(this, tr("Error!"), error);
261 		}
262 	}
263 }
264 
exportBookmarks()265 void BookmarkManageDlg::exportBookmarks()
266 {
267 	QString fileName = FileUtil::getSaveFileName(this, tr("Export bookmarks"), "bookmarks.txt");
268 	if(fileName.isEmpty())
269 		return;
270 
271 	QFile file(fileName);
272 	if(file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) {
273 		QDomDocument doc;
274 		QDomElement root = doc.createElement("bookmarks");
275 		doc.appendChild(root);
276 		for (int row = 0; row < model_->rowCount(); ++row) {
277 			QModelIndex index = model_->index(row, 0, QModelIndex());
278 			ConferenceBookmark cb = bookmarkFor(index);
279 			root.appendChild(cb.toXml(doc));
280 		}
281 		file.write(doc.toString().toLocal8Bit());
282 	}
283 }
284