root/trunk/qt4-gui/src/dialogs/gpgkeymanager.cpp

Revision 6463, 7.1 kB (checked in by flynd, 4 months ago)

Use a const pointer for user objects that are only fetched for read access. Fixed some places where we changed the user even though we just had a read lock.

  • Property svn:eol-style set to native
Line 
1/*
2 * This file is part of Licq, an instant messaging client for UNIX.
3 * Copyright (C) 2005-2006 Licq developers
4 *
5 * Licq is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * Licq 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 Licq; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18 */
19
20#include "gpgkeymanager.h"
21
22#include "config.h"
23
24#include <QDialogButtonBox>
25#include <QMenu>
26#include <QPushButton>
27#include <QVBoxLayout>
28
29#include <licq_events.h>
30#include <licq_icqd.h>
31#include <licq_user.h>
32
33#include "core/mainwin.h"
34#include "core/messagebox.h"
35
36#include "helpers/support.h"
37
38#include "gpgkeyselect.h"
39
40using namespace LicqQtGui;
41/* TRANSLATOR LicqQtGui::GPGKeyManager */
42/* TRANSLATOR LicqQtGui::KeyListItem */
43
44struct luser
45{
46  QString szId;
47  unsigned long nPPID;
48  QString alias;
49};
50
51bool compare_luser(const struct luser& left, const struct luser& right)
52{
53  return QString::compare(left.alias, right.alias, Qt::CaseInsensitive) <= 0;
54}
55
56GPGKeyManager::GPGKeyManager(QWidget* parent)
57  : QDialog(parent)
58{
59  setAttribute(Qt::WA_DeleteOnClose, true);
60  Support::setWidgetProps(this, "GPGKeyManager");
61  setWindowTitle(tr("Licq GPG Key Manager"));
62
63  QVBoxLayout* lay_main = new QVBoxLayout(this);
64
65  lst_keyList = new KeyList();
66  lst_keyList->setAllColumnsShowFocus(true);
67  QStringList headers;
68  headers << tr("User") << tr("Active") << tr("Key ID");
69  lst_keyList->setHeaderLabels(headers);
70  connect(lst_keyList, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)),
71      SLOT(slot_doubleClicked(QTreeWidgetItem*)));
72  lay_main->addWidget(lst_keyList);
73
74  QDialogButtonBox* buttons = new QDialogButtonBox();
75  lay_main->addWidget(buttons);
76
77  QPushButton* btn;
78#define BUTTON(role, name, slot) \
79  btn = buttons->addButton(name, QDialogButtonBox::role); \
80  connect(btn, SIGNAL(clicked()), SLOT(slot()))
81
82  BUTTON(ActionRole, tr("&Add"), slot_add);
83  BUTTON(ActionRole, tr("&Edit"), slot_edit);
84  BUTTON(ActionRole, tr("&Remove"), slot_remove);
85
86#undef BUTTON
87  buttons->addButton(QDialogButtonBox::Close);
88  connect(buttons, SIGNAL(rejected()), SLOT(close()));
89
90  initKeyList();
91
92  show();
93}
94
95void GPGKeyManager::slot_edit()
96{
97  slot_doubleClicked(lst_keyList->currentItem());
98}
99
100void GPGKeyManager::slot_doubleClicked(QTreeWidgetItem* item)
101{
102  if (item != NULL)
103    dynamic_cast<KeyListItem*>(item)->edit();
104}
105
106void GPGKeyManager::slot_add()
107{
108  QMenu popupMenu;
109  QList<luser> list;
110
111  FOR_EACH_USER_START(LOCK_R)
112  {
113    if (strcmp(pUser->GPGKey(), "") == 0)
114    {
115      luser tmp;
116      tmp.szId = pUser->IdString();
117      tmp.nPPID = pUser->PPID();
118      tmp.alias = QString::fromUtf8(pUser->GetAlias());
119      list.append(tmp);
120    }
121  }
122  FOR_EACH_USER_END
123
124  qSort(list.begin(), list.end(), compare_luser);
125
126  for (int i = 0; i < list.count(); i++)
127    popupMenu.addAction(list.at(i).alias)->setData(i);
128
129  QAction* res = popupMenu.exec(QCursor::pos());
130  if (res == NULL)
131    return;
132  const luser* tmp = &list.at(res->data().toInt());
133  if (tmp == NULL)
134    return;
135
136  lst_keyList->editUser(tmp->szId, tmp->nPPID);
137}
138
139void GPGKeyManager::slot_remove()
140{
141  KeyListItem* item = (KeyListItem*)lst_keyList->currentItem();
142  if (item != NULL)
143  {
144    if (QueryYesNo(this, tr("Do you want to remove the GPG key binding for the user %1?\n"
145            "The key isn't deleted from your keyring.")
146          .arg(item->text(0))))
147    {
148      item->unsetKey();
149      delete item;
150      lst_keyList->resizeColumnsToContents();
151    }
152  }
153}
154
155void GPGKeyManager::initKeyList()
156{
157  FOR_EACH_USER_START(LOCK_R)
158  {
159    if (strcmp(pUser->GPGKey(), "") != 0)
160    {
161      new KeyListItem(lst_keyList, pUser);
162    }
163  }
164  FOR_EACH_USER_END
165
166  lst_keyList->resizeColumnsToContents();
167}
168
169// THE KEYLIST
170KeyList::KeyList(QWidget* parent)
171  : QTreeWidget(parent)
172{
173  setAcceptDrops(true);
174  setRootIsDecorated(false);
175}
176
177void KeyList::editUser(QString id, unsigned long ppid)
178{
179  KeyListItem* item = NULL;
180  bool found = false;
181
182  for (int i = 0; i < topLevelItemCount(); ++i)
183  {
184    item = dynamic_cast<KeyListItem*>(topLevelItem(i));
185
186    if (item->getszId() == id && item->getnPPID() == ppid)
187    {
188      found = true;
189      break;
190    }
191  }
192
193  if (!found)
194  {
195    const ICQUser* u = gUserManager.FetchUser(id.toLatin1(), ppid, LOCK_R);
196    if (u == NULL)
197      return;
198    item = new KeyListItem(this, u);
199    gUserManager.DropUser(u);
200    resizeColumnsToContents();
201  }
202
203  item->edit();
204};
205
206void KeyList::dragEnterEvent(QDragEnterEvent* event)
207{
208  if (event->mimeData()->hasText())
209    event->acceptProposedAction();
210}
211
212void KeyList::dropEvent(QDropEvent* event)
213{
214  if (!event->mimeData()->hasText())
215    return;
216
217  QString text = event->mimeData()->text();
218
219  if (text.length() <= 4)
220    return;
221
222  unsigned long nPPID = 0;
223  FOR_EACH_PROTO_PLUGIN_START(gLicqDaemon)
224  {
225    if (text.startsWith(PPIDSTRING((*_ppit)->PPID())))
226    {
227      nPPID = (*_ppit)->PPID();
228      break;
229    }
230  }
231  FOR_EACH_PROTO_PLUGIN_END;
232
233  if (nPPID == 0)
234    return;
235
236  editUser(text.mid(4), nPPID);
237}
238
239void KeyList::resizeEvent(QResizeEvent* e)
240{
241  QTreeWidget::resizeEvent(e);
242
243  int totalWidth = 0;
244  int nNumCols = columnCount();
245  for (int i = 1; i < nNumCols; ++i)
246    totalWidth += columnWidth(i);
247
248  int newWidth = width() - totalWidth - 2;
249  if (newWidth <= 0)
250  {
251    setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
252    setColumnWidth(0, 2);
253  }
254  else
255  {
256    setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
257    setColumnWidth(0, newWidth);
258  }
259}
260
261void KeyList::resizeColumnsToContents()
262{
263  for (int i = 0; i < columnCount(); i++)
264    resizeColumnToContents(i);
265}
266
267// KEYLISTITEM
268KeyListItem::KeyListItem(QTreeWidget* parent, const ICQUser* u)
269  : QTreeWidgetItem(parent),
270    szId(u->IdString()),
271    nPPID(u->PPID()),
272    keySelect(NULL)
273{
274  updateText(u);
275}
276
277void KeyListItem::updateText(const ICQUser* u)
278{
279  setText(0, QString::fromUtf8(u->GetAlias()));
280  setText(1, u->UseGPG() ? tr("Yes") : tr("No"));
281  setText(2, u->GPGKey());
282}
283
284void KeyListItem::edit()
285{
286  if (keySelect == NULL)
287  {
288    keySelect = new GPGKeySelect(szId, nPPID);
289    connect(keySelect, SIGNAL(signal_done()), SLOT(slot_done()));
290  }
291}
292
293void KeyListItem::slot_done()
294{
295  const ICQUser* u = gUserManager.FetchUser(szId.toLatin1(), nPPID, LOCK_R);
296  keySelect = NULL;
297
298  if (u != NULL)
299  {
300    if (strcmp(u->GPGKey(), "") == 0)
301      delete this;
302    else
303      updateText(u);
304    gUserManager.DropUser(u);
305    dynamic_cast<KeyList*>(treeWidget())->resizeColumnsToContents();
306  }
307}
308
309void KeyListItem::unsetKey()
310{
311  ICQUser* u = gUserManager.FetchUser(szId.toLatin1(), nPPID, LOCK_W);
312
313  if (u != NULL)
314  {
315    u->SetUseGPG(false);
316    u->SetGPGKey("");
317    gUserManager.DropUser(u);
318    CICQSignal s(SIGNAL_UPDATExUSER, USER_GENERAL, szId.toLatin1(), nPPID);
319    gMainWindow->slot_updatedUser(&s);
320  }
321}
Note: See TracBrowser for help on using the browser.