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

Revision 6463, 7.3 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 "gpgkeyselect.h"
21
22#include "config.h"
23
24#include <cstring>
25#include <gpgme.h>
26
27#include <QCheckBox>
28#include <QDialogButtonBox>
29#include <QHBoxLayout>
30#include <QHeaderView>
31#include <QLabel>
32#include <QLineEdit>
33#include <QPushButton>
34#include <QVBoxLayout>
35
36#include <licq_user.h>
37#include <licq_events.h>
38
39#include "core/mainwin.h"
40
41#include "helpers/support.h"
42
43using namespace LicqQtGui;
44/* TRANSLATOR LicqQtGui::GPGKeySelect */
45/* TRANSLATOR LicqQtGui::KeyView */
46
47GPGKeySelect::GPGKeySelect(QString id, unsigned long ppid, QWidget* parent)
48  : QDialog(parent),
49    szId(id),
50    nPPID(ppid)
51{
52  if (id.isNull() || !nPPID)
53    return;
54
55  setAttribute(Qt::WA_DeleteOnClose, true);
56  Support::setWidgetProps(this, "GPGKeySelectDialog");
57
58  const ICQUser* u = gUserManager.FetchUser(szId.toLatin1(), nPPID, LOCK_R);
59  if (u == NULL)
60    return;
61
62  setWindowTitle(tr("Select GPG Key for user %1")
63      .arg(QString::fromUtf8(u->GetAlias())));
64
65  QVBoxLayout* top_lay = new QVBoxLayout(this);
66
67  top_lay->addWidget(new QLabel(tr("Select a GPG key for user %1.")
68        .arg(QString::fromUtf8(u->GetAlias()))));
69  if (strcmp(u->GPGKey(), "") == 0)
70    top_lay->addWidget(new QLabel(tr("Current key: No key selected")));
71  else
72    top_lay->addWidget(new QLabel(tr("Current key: %1")
73          .arg(QString::fromLocal8Bit(u->GPGKey()))));
74
75  useGPG = new QCheckBox(tr("Use GPG Encryption"));
76  useGPG->setChecked(u->UseGPG() || strcmp(u->GPGKey(), "") == 0);
77  top_lay->addWidget(useGPG);
78
79  // Filter
80  QHBoxLayout* filterLayout = new QHBoxLayout();
81  top_lay->addLayout(filterLayout);
82  filterLayout->addWidget(new QLabel(tr("Filter:")));
83  QLineEdit* filterText = new QLineEdit();
84  filterText->setFocus();
85  connect(filterText, SIGNAL(textChanged(const QString&)),
86      SLOT(filterTextChanged(const QString&)));
87  filterLayout->addWidget(filterText);
88
89  gUserManager.DropUser(u);
90
91  // public keys
92  keySelect = new KeyView(szId, nPPID);
93  top_lay->addWidget(keySelect);
94  connect(keySelect, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)),
95      SLOT(slot_doubleClicked(QTreeWidgetItem*, int)));
96
97  QDialogButtonBox* buttons = new QDialogButtonBox(
98      QDialogButtonBox::Ok |
99      QDialogButtonBox::Cancel |
100      QDialogButtonBox::Discard);
101
102  QPushButton* btnNoKey = buttons->button(QDialogButtonBox::Discard);
103  btnNoKey->setText(tr("&No Key"));
104
105  connect(buttons, SIGNAL(accepted()), SLOT(slot_ok()));
106  connect(buttons, SIGNAL(rejected()), SLOT(slotCancel()));
107  connect(btnNoKey, SIGNAL(clicked()), SLOT(slotNoKey()));
108
109  top_lay->addWidget(buttons);
110
111  show();
112}
113
114GPGKeySelect::~GPGKeySelect()
115{
116  emit signal_done();
117}
118
119void GPGKeySelect::filterTextChanged(const QString& str)
120{
121  for (int i = 0; i < keySelect->topLevelItemCount(); ++i)
122  {
123    QTreeWidgetItem* item = keySelect->topLevelItem(i);
124    item->setHidden(!item->text(0).contains(str, Qt::CaseInsensitive) &&
125        !item->text(1).contains(str, Qt::CaseInsensitive) &&
126        !item->text(2).contains(str, Qt::CaseInsensitive));
127  }
128}
129
130void GPGKeySelect::slot_doubleClicked(QTreeWidgetItem* item, int /* column */)
131{
132  if ( item )
133    slot_ok();
134}
135
136void GPGKeySelect::slot_ok()
137{
138  QTreeWidgetItem* curItem = keySelect->currentItem();
139
140  if (curItem != NULL)
141  {
142    if (curItem->parent() != NULL)
143      curItem = curItem->parent();
144
145    ICQUser* u = gUserManager.FetchUser(szId.toLatin1(), nPPID, LOCK_W);
146    if (u != NULL)
147    {
148      u->SetGPGKey(curItem->text(2).toAscii());
149      u->SetUseGPG(useGPG->isChecked());
150      gUserManager.DropUser(u);
151      updateIcon();
152    }
153  }
154
155  close();
156}
157
158void GPGKeySelect::updateIcon()
159{
160  CICQSignal s(SIGNAL_UPDATExUSER, USER_GENERAL, szId.toLatin1(), nPPID);
161  gMainWindow->slot_updatedUser(&s);
162  return;
163}
164
165void GPGKeySelect::slotNoKey()
166{
167  ICQUser* u = gUserManager.FetchUser(szId.toLatin1(), nPPID, LOCK_W);
168  if ( u )
169  {
170    u->SetGPGKey( "" );
171    gUserManager.DropUser( u );
172    updateIcon();
173  }
174
175  close();
176};
177
178void GPGKeySelect::slotCancel()
179{
180  close();
181}
182
183gpgme_ctx_t mCtx;
184gpgme_key_t key;
185
186
187KeyView::KeyView(QString id, unsigned long ppid, QWidget* parent)
188  : QTreeWidget(parent),
189    szId(id),
190    nPPID(ppid)
191{
192  header()->setClickable(false);
193  QStringList headers;
194  headers << tr("Name") << tr("EMail") << tr("ID");
195  setHeaderLabels(headers);
196
197  setAllColumnsShowFocus(true);
198
199  initKeyList();
200
201  setRootIsDecorated(true);
202}
203
204void KeyView::resizeEvent(QResizeEvent* event)
205{
206  QTreeWidget::resizeEvent(event);
207
208  unsigned short totalWidth = 0;
209  int nNumCols = columnCount();
210  for (int i = 0; i < nNumCols - 1; i++)
211    totalWidth += columnWidth(i);
212
213  int newWidth = width() - totalWidth - 2;
214  if (newWidth <= 0)
215  {
216    setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
217    setColumnWidth(nNumCols - 1, 2);
218  }
219  else
220  {
221    setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
222    setColumnWidth(nNumCols - 1, newWidth);
223  }
224}
225
226void KeyView::testViewItem(QTreeWidgetItem* item, const ICQUser* u)
227{
228  int val = 0;
229  for (int i = 0; i < 2; ++i)
230  {
231    if (item->text(i).contains(u->GetFirstName(), Qt::CaseInsensitive))
232      val++;
233    if (item->text(i).contains(u->GetLastName(), Qt::CaseInsensitive))
234      val++;
235    if (item->text(i).contains(u->GetAlias(), Qt::CaseInsensitive))
236      val++;
237    if (item->text(i).contains(u->GetEmailPrimary(), Qt::CaseInsensitive))
238      val++;
239  }
240
241  if (item->text(2).contains(u->GPGKey(), Qt::CaseInsensitive))
242    val += 10;
243
244  if (val > maxItemVal)
245  {
246    maxItemVal = val;
247    maxItem = item;
248  }
249}
250
251void KeyView::initKeyList()
252{
253  gpgme_new(&mCtx);
254
255  const ICQUser* u = gUserManager.FetchUser(szId.toLatin1(), nPPID, LOCK_R);
256  maxItemVal = -1;
257  maxItem = NULL;
258
259  int err = gpgme_op_keylist_start(mCtx, NULL, 0);
260
261  while (!err)
262  {
263    err = gpgme_op_keylist_next(mCtx, &key);
264    if (err)
265      break;
266    gpgme_user_id_t uid = key->uids;
267    if (uid && key->can_encrypt && key->subkeys)
268    {
269      QStringList fColumns;
270      fColumns << QString::fromUtf8(uid->name);
271      fColumns << QString::fromUtf8(uid->email);
272      fColumns << QString(key->subkeys->keyid).right(8);
273      QTreeWidgetItem* f = new QTreeWidgetItem(this, fColumns);
274      if (u)
275        testViewItem(f, u);
276      uid = uid->next;
277      while (uid)
278      {
279        QStringList gColumns;
280        gColumns << QString::fromUtf8(uid->name);
281        gColumns << QString::fromUtf8(uid->email);
282        QTreeWidgetItem* g = new QTreeWidgetItem(f, gColumns);
283        if (u)
284          testViewItem(g, u);
285        uid = uid->next;
286      }
287    }
288    gpgme_key_release(key);
289  }
290
291  if (u)
292    gUserManager.DropUser(u);
293
294  gpgme_release(mCtx);
295  if (maxItem)
296    setCurrentItem(maxItem);
297}
Note: See TracBrowser for help on using the browser.