/[winpt]/trunk/Src/wptKeyManagerDlg.cpp
ViewVC logotype

Contents of /trunk/Src/wptKeyManagerDlg.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 129 - (show annotations)
Fri Dec 30 13:56:10 2005 UTC (19 years, 2 months ago) by twoaday
File size: 59003 byte(s)
2005-12-27  Timo Schulz  <ts@g10code.com>
                                                                                
        * wptListView.cpp (listview_set_view): New.
        (listview_del_column): New.
        * wptW32API.cpp (get_locale_date): New.
        (get_menu_state): New.
        (force_foreground_window): New.
        * wptVerifyList.cpp (strtimestamp): Support for
        locale date formats.
        * wptGPGUtil.cpp (gpg_revoke_cert): Handle bad
        passphrases.
        * wptKeyEditCB.cpp (editkey_command_handler): Immediately
        return when a bad passphrase was submitted.
        * wptKeyRevokersDlg.cpp (keyrevokers_dlg_proc): Change
        column order.
        * wptKeylist.cpp (keylist_upd_col): New.
        * wptKeyManagerDlg.cpp (update_ui_items): Deactivate
        'Revocation' for public keys.
        (translate_menu_strings): s/Revoke/Revoke Cert.
        (modify_listview_columns): New.


1 /* wptKeyManagerDlg.cpp - WinPT Key Manager
2 * Copyright (C) 2000-2005 Timo Schulz
3 * Copyright (C) 2004 Andreas Jobs
4 *
5 * This file is part of WinPT.
6 *
7 * WinPT is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * WinPT is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with WinPT; if not, write to the Free Software Foundation,
19 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20 */
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24
25 #include <windows.h>
26 #include <commctrl.h>
27
28 #include "resource.h"
29 #include "wptTypes.h"
30 #include "wptGPG.h"
31 #include "wptCommonCtl.h"
32 #include "wptContext.h" /* for passphrase_s */
33 #include "wptDlgs.h"
34 #include "wptW32API.h"
35 #include "wptVersion.h"
36 #include "wptKeylist.h"
37 #include "wptNLS.h"
38 #include "wptErrors.h"
39 #include "wptHotkey.h"
40 #include "wptKeyManager.h"
41 #include "wptKeyserver.h"
42 #include "wptKeyEdit.h"
43 #include "wptRegistry.h"
44 #include "wptUTF8.h"
45
46 /* Name and ID of the separator window. */
47 #define KM_SEPARATOR_ID 10000
48 #define WINDOWCLASS_SEPARATOR_CHILD "WINPT_SEP_CHILD"
49
50 /* Virtual key codes. */
51 #ifndef VK_F
52 #define VK_F 70
53 #endif
54 #ifndef VK_A
55 #define VK_A 65
56 #endif
57 #ifndef VK_C
58 #define VK_C 67
59 #endif
60 #ifndef VK_P
61 #define VK_P 80
62 #endif
63
64 static subclass_s keylist_proc;
65
66 HIMAGELIST glob_imagelist;
67
68 struct km_info_s {
69 /* Window positions */
70 int pos_x, pos_y;
71 int ypos_sep;
72 int ypercent_sep;
73
74 HWND hwnd_sep;
75 HWND toolbar;
76 HWND statbar;
77
78 listview_ctrl_t lv;
79 int lv_idx;
80 int keylist_sortby;
81 };
82
83 /* Toolbar button structure. */
84 struct mybuttons {
85 long icon;
86 long command;
87 char *text;
88 };
89
90 struct mybuttons myb[] = {
91 {IMI_KEY_DELETE, ID_KEYMISC_DELETE, "Delete"},
92 {IMI_KEY_PROPS, ID_KEYMISC_PROPS, "Properties"},
93 {IMI_KEY_SIGN, ID_KEYMISC_SIGN, "Sign"},
94 {IMI_KEY_IMPORT, ID_KEYMISC_IMPORT, "Import"},
95 {IMI_KEY_EXPORT, ID_KEYMISC_EXPORT, "Export"},
96 };
97
98
99 /* Subclass the keylist listview control to allow extended commands. */
100 static BOOL CALLBACK
101 keylist_subclass_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
102 {
103 struct listview_ctrl_s lv;
104
105 switch (msg) {
106 case WM_LBUTTONDBLCLK:
107 send_cmd_id (keylist_proc.dlg, ID_KEYMISC_PROPS);
108 break;
109
110 case WM_KEYUP:
111 int virt_key = (int)wparam;
112 switch (virt_key) {
113 case VK_SPACE:
114 send_cmd_id (keylist_proc.dlg, ID_KEYMISC_PROPS);
115 break;
116
117 case VK_DELETE:
118 send_cmd_id (keylist_proc.dlg, ID_KEYMISC_DELETE);
119 break;
120
121 case VK_INSERT:
122 send_cmd_id (keylist_proc.dlg, ID_KEYMISC_PASTE);
123 break;
124
125 case VK_A:
126 if (GetAsyncKeyState (VK_CONTROL)) {
127 lv.ctrl = GetDlgItem (keylist_proc.dlg, IDC_KEYMISC_KEYLIST);
128 listview_select_all (&lv);
129 }
130 break;
131
132 case VK_C:
133 if (GetAsyncKeyState (VK_CONTROL)) {
134 lv.ctrl = GetDlgItem (keylist_proc.dlg, IDC_KEYMISC_KEYLIST);
135 km_clip_export (keylist_proc.dlg, &lv);
136 }
137 break;
138
139 case VK_P:
140 if (GetAsyncKeyState (VK_CONTROL))
141 km_clip_import (keylist_proc.dlg);
142 break;
143
144 case VK_F:
145 if (GetAsyncKeyState (VK_CONTROL)) {
146 lv.ctrl = GetDlgItem (keylist_proc.dlg, IDC_KEYMISC_KEYLIST);
147 km_find_key (dlg, &lv);
148 }
149 break;
150 }
151 break;
152 }
153
154 return CallWindowProc (keylist_proc.old, dlg, msg, wparam, lparam);
155 }
156
157
158 static HWND
159 load_toolbar (HWND dlg, struct km_info_s *kmi)
160 {
161 HWND tbwnd;
162 TBSAVEPARAMS tbsp;
163 TBBUTTON tb_buttons[] = {
164 /*{imagelist_getindex(IMI_EXIT), ID_KEYMISC_QUIT, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0L, 0},*/
165 {imagelist_getindex(IMI_KEY_DELETE), ID_KEYMISC_DELETE, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0}, 0L, 0},
166 {imagelist_getindex(IMI_KEY_PROPS), ID_KEYMISC_PROPS, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0}, 0L, 0},
167 {imagelist_getindex(IMI_KEY_SIGN), ID_KEYMISC_SIGN, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0}, 0L, 0},
168 {0, 0, 0, TBSTYLE_SEP, {0}, 0L, 0},
169 {imagelist_getindex(IMI_KEY_IMPORT), ID_KEYMISC_IMPORT, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0}, 0L, 0},
170 {imagelist_getindex(IMI_KEY_EXPORT), ID_KEYMISC_EXPORT, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0}, 0L, 0},
171 };
172
173 tbwnd = CreateWindowEx (0, TOOLBARCLASSNAME, NULL,
174 WS_CHILD|TBSTYLE_TOOLTIPS|TBSTYLE_FLAT|CCS_ADJUSTABLE,
175 0, 0, 0, 0, dlg, (HMENU)IDR_WINPT_KMTB, glob_hinst, NULL);
176 if (tbwnd) {
177 SendMessage (tbwnd, TB_BUTTONSTRUCTSIZE, (WPARAM) sizeof(TBBUTTON), 0);
178 SendMessage (tbwnd, TB_SETIMAGELIST, 0, (LPARAM)glob_imagelist);
179 SendMessage (tbwnd, TB_AUTOSIZE, 0, 0);
180 ShowWindow (tbwnd, SW_SHOW);
181
182 /* Restore toolbar */
183 tbsp.hkr = HKEY_CURRENT_USER;
184 tbsp.pszSubKey = "Software\\WinPT";
185 tbsp.pszValueName = "KM_toolbar";
186 if (SendMessage(tbwnd, TB_SAVERESTORE, FALSE, (LPARAM)&tbsp ) == 0)
187 SendMessage (tbwnd, TB_ADDBUTTONS, sizeof(tb_buttons) / sizeof(tb_buttons[0]),
188 (LONG)&tb_buttons[0]);
189 }
190 return tbwnd;
191 }
192
193
194 /* Restore the width of the columns from the registry.
195 If no bitstring was found, the default size is used. */
196 int
197 restore_column_info (listview_ctrl_t hd)
198 {
199 WORD *buf;
200 HKEY root;
201 DWORD type;
202 DWORD size = hd->cols*sizeof (WORD), i;
203 LONG ec;
204
205 ec = RegOpenKeyEx (HKEY_CURRENT_USER, "Software\\WinPT", 0,
206 KEY_ALL_ACCESS, &root);
207 if (ec != ERROR_SUCCESS)
208 return -1;
209
210 buf = new WORD[size/2];
211 if (!buf)
212 BUG (NULL);
213 ec = RegQueryValueEx (root, "KMColumnSize", NULL, &type,
214 (BYTE*)buf, &size);
215 RegCloseKey (root);
216 if (ec != ERROR_SUCCESS) {
217 free_if_alloc (buf);
218 return -1;
219 }
220
221 /* check for garbled values. */
222 for (i=0; i < size/2; i++) {
223 if (buf[i] == 0 || buf[i] > 512) {
224 free_if_alloc (buf);
225 return -1;
226 }
227 }
228 for (i=0; i < size/2; i++) {
229 LVCOLUMN lvc;
230
231 memset (&lvc, 0, sizeof (lvc));
232 lvc.mask = LVCF_WIDTH;
233 lvc.cx = buf[i];
234 ListView_SetColumn (hd->ctrl, i, &lvc);
235 }
236 free_if_alloc (buf);
237 return 0;
238 }
239
240
241 /* Save the current column width to the registry. */
242 int
243 save_column_info (listview_ctrl_t hd)
244 {
245 WORD *buf;
246 HKEY root;
247 LONG ec;
248 int i;
249
250 buf = new WORD[hd->cols];
251 if (!buf)
252 BUG (NULL);
253 for (i=0; i < hd->cols; i++) {
254 LVCOLUMN lvc;
255
256 memset (&lvc, 0, sizeof (lvc));
257 lvc.mask = LVCF_WIDTH;
258 ListView_GetColumn (hd->ctrl, i, &lvc);
259 buf[i] = lvc.cx;
260 }
261
262 ec = RegOpenKeyEx (HKEY_CURRENT_USER, "Software\\WinPT", 0,
263 KEY_ALL_ACCESS, &root);
264 if (ec != ERROR_SUCCESS) {
265 free_if_alloc (buf);
266 return -1;
267 }
268
269 ec = RegSetValueEx (root, "KMColumnSize", 0, REG_BINARY,
270 (const BYTE*)buf, 2*hd->cols);
271 RegCloseKey (root);
272 free_if_alloc (buf);
273 return ec == ERROR_SUCCESS? 0 : -1;
274 }
275
276
277 /* Center window @dlg. */
278 static void
279 do_center_window (HWND dlg, struct km_info_s *kmi)
280 {
281 RECT rect;
282 char *p;
283 int pos_x = 0;
284 int pos_y = 0;
285
286 /* Find bottom of keylist */
287 GetWindowRect (GetDlgItem(dlg, IDC_KEYMISC_KEYLIST), &rect);
288 MapWindowPoints (NULL, dlg, (POINT*)&rect, 2);
289
290 kmi->ypos_sep = rect.bottom;
291
292 p = get_reg_entry (HKEY_CURRENT_USER, "Software\\WinPT", "KM_Pos_X");
293 if (p && !strcmp (p, " ")) {
294 free_if_alloc (p);
295 center_window (dlg, NULL);
296 return;
297 }
298 else if (p)
299 pos_x = atol (p);
300
301 p = get_reg_entry (HKEY_CURRENT_USER, "Software\\WinPT", "KM_Pos_Y");
302 if (p && !strcmp (p, " ")) {
303 free_if_alloc (p);
304 center_window (dlg, NULL);
305 return;
306 }
307 else if (p)
308 pos_y = atol (p);
309
310 if (!pos_y && !pos_x) {
311 center_window (dlg, NULL);
312 return;
313 }
314
315 if (pos_x < 0 || pos_y < 0)
316 pos_x = pos_y = 0;
317 if (pos_x > GetSystemMetrics (SM_CXSCREEN)
318 || pos_y > GetSystemMetrics (SM_CYSCREEN)) {
319 pos_x = pos_y = 0;
320 }
321 GetClientRect (dlg, &rect);
322 MoveWindow (dlg, pos_x, pos_y, rect.right, rect.bottom, TRUE);
323 }
324
325
326 /* Resize the key manager window with the information from @kmi. */
327 static void
328 do_resize_window (HWND dlg, struct km_info_s *kmi)
329 {
330 HWND h;
331 RECT rclient, rect;
332 BOOL bRepaint = FALSE;
333
334 /* Get rect of client area and make life easier */
335 GetClientRect (dlg, &rclient);
336
337 /* Move toolbar to the top of the window */
338 if (kmi->toolbar) {
339 GetWindowRect (kmi->toolbar, &rect);
340 ScreenToClient (dlg, (POINT*)&rect);
341 ScreenToClient (dlg, (POINT*)&(rect.right));
342
343 rclient.top += rect.bottom - rect.top;
344 MoveWindow (kmi->toolbar, 0, 0, rclient.right - rclient.left,
345 rect.bottom - rect.top, bRepaint);
346 }
347
348 /* Move statusbar to the bottom of the window */
349 if (kmi->statbar) {
350 GetWindowRect (kmi->statbar, &rect);
351 ScreenToClient (dlg, (POINT*)&rect);
352 ScreenToClient (dlg, (POINT*)&(rect.right));
353
354 rclient.bottom -= rect.bottom - rect.top;
355 MoveWindow (kmi->statbar, 0, rclient.bottom,
356 rclient.right - rclient.left,
357 rect.bottom - rect.top, bRepaint);
358 }
359
360 /* Obtain separator information and move it to the desired posistion */
361 if (kmi->ypercent_sep)
362 kmi->ypos_sep = (rclient.bottom - rclient.top) * kmi->ypercent_sep / 100;
363 else
364 kmi->ypercent_sep = kmi->ypos_sep * 100 / (rclient.bottom - rclient.top);
365
366 /* Don't move away */
367 if (kmi->ypos_sep+5 > rclient.bottom)
368 kmi->ypos_sep = rclient.bottom - 5;
369 if (kmi->ypos_sep < rclient.top)
370 kmi->ypos_sep = rclient.top;
371 MoveWindow (kmi->hwnd_sep, 0, kmi->ypos_sep,
372 (rclient.right - rclient.left), 5, bRepaint);
373
374 /* Place the keylist above the separator */
375 h = GetDlgItem (dlg, IDC_KEYMISC_KEYLIST);
376 MoveWindow (h, rclient.left, rclient.top, rclient.right - rclient.left,
377 kmi->ypos_sep - rclient.top, bRepaint);
378 rclient.top = kmi->ypos_sep + 5 + 8;
379
380 /* Place the group text and the group box below the separator */
381 h = GetDlgItem (dlg, IDC_KEYMISC_GTEXT);
382 MoveWindow (h, rclient.left, rclient.top, 100, 14, bRepaint);
383 rclient.top += 18;
384
385 h = GetDlgItem (dlg, IDC_KEYMISC_GROUP);
386 MoveWindow (h, rclient.left, rclient.top, rclient.right - rclient.left,
387 (rclient.bottom < rclient.top) ?
388 0 : rclient.bottom - rclient.top, bRepaint);
389
390 /* Repaint the whole thing */
391 InvalidateRect (dlg, NULL, TRUE);
392 }
393
394
395 /* Return true if the clipboard contains an OpenPGP key. */
396 static bool
397 clip_contains_pgpkey (void)
398 {
399 char *ctxt;
400 bool val = false;
401
402 ctxt = get_clip_text (NULL);
403 if (!ctxt || strlen (ctxt) < 512)
404 val = false;
405 else if (strstr (ctxt, "BEGIN PGP") && strstr (ctxt, "KEY BLOCK") &&
406 strstr (ctxt, "END PGP"))
407 val = true;
408 free_if_alloc (ctxt);
409 return val;
410 }
411
412
413 /* Show a mini popup menu to import keys. */
414 static void
415 do_create_minpopup (HWND dlg)
416 {
417 HMENU hm;
418 MENUITEMINFO mi;
419 char * s;
420 POINT p;
421
422 if (gpg_read_only || !clip_contains_pgpkey ())
423 return;
424 hm = CreatePopupMenu ();
425 if (!hm)
426 BUG( NULL );
427 memset (&mi, 0, sizeof mi);
428 mi.cbSize = sizeof mi;
429 s = (char *)_("Paste Key from Clipboard");
430 mi.fType = MF_STRING;
431 mi.dwTypeData = s;
432 mi.cch = strlen (s);
433 mi.fMask = MIIM_DATA | MIIM_ID | MIIM_TYPE;
434 mi.wID = ID_KEYCTX_PASTE;
435 InsertMenuItem (hm, 0, FALSE, &mi);
436 GetCursorPos (&p);
437 TrackPopupMenu (hm, 0, p.x, p.y, 0, dlg, NULL);
438 DestroyMenu (hm);
439 }
440
441
442 /* Update the default key entry in the status bar for dialog @dlg. */
443 void
444 update_default_key_str (HWND dlg)
445 {
446 const char *fmt;
447 char *keyid;
448 char defkeyinf[128];
449
450 /* XXX: also show the name? */
451 keyid = get_gnupg_default_key ();
452 if (!keyid)
453 return;
454 if ((keyid[0] >= 'A' && keyid[0] <= 'Z') ||
455 (keyid[0] >= 'a' && keyid[0] <= 'z') ||
456 (keyid[0] == '0' && keyid[1] == 'x'))
457 fmt = _("Default Key: %s");
458 else
459 fmt = _("Default Key: 0x%s");
460 _snprintf (defkeyinf, sizeof (defkeyinf) - 1, fmt, keyid);
461 SendMessage (dlg, SB_SETTEXT, 0, (LPARAM)defkeyinf);
462 free_if_alloc (keyid);
463 }
464
465
466 /* Count all keys and show from @lv results in the status bar @sb. */
467 void
468 update_status_bar (HWND sb, listview_ctrl_t lv)
469 {
470 char txt_sec[128], txt_pub[128];
471 int nkeys = 0, nsec = 0;
472 int i;
473
474 nkeys = listview_count_items (lv, 0);
475 for (i = 0; i < nkeys; i++) {
476 if (km_check_for_seckey (lv, i, NULL))
477 nsec++;
478 }
479 _snprintf (txt_sec, sizeof (txt_sec)-1, _("%d secret keys"), nsec);
480 _snprintf (txt_pub, sizeof (txt_pub)-1, _("%d keys"), nkeys);
481 SendMessage (sb, SB_SETTEXT, 1, (LPARAM)txt_sec);
482 SendMessage (sb, SB_SETTEXT, 2, (LPARAM)txt_pub);
483 }
484
485
486
487 /* Reload the key cache if requested. */
488 static void
489 do_check_cache (listview_ctrl_t lv, HWND dlg, HWND sb)
490 {
491 gpg_keycache_t cache;
492
493 if (keycache_get_reload ()) {
494 keycache_reload (dlg);
495 keycache_set_reload (0);
496 cache = keycache_get_ctx (1);
497 if (!cache)
498 BUG (dlg);
499 keylist_reload (lv, cache, KEYLIST_LIST, KEY_SORT_USERID);
500 update_status_bar (sb, lv);
501 }
502 }
503
504
505 long CALLBACK
506 separator_wnd_proc (HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
507 {
508 static POINT last_mouse_pos;
509
510 if (msg == WM_CREATE)
511 SetWindowLong (hwnd, GWL_USERDATA,
512 (long)(((CREATESTRUCT*)lparam)->lpCreateParams));
513
514 switch (msg) {
515 case WM_PAINT:
516 PAINTSTRUCT ps;
517 RECT rect;
518 HPEN hpen;
519
520 GetClientRect (hwnd, &rect);
521 BeginPaint (hwnd, &ps);
522
523 /* Background */
524 FillRect (ps.hdc, &rect, (HBRUSH)(COLOR_3DFACE+1));
525
526 /* The lines from the light into the dark */
527 MoveToEx(ps.hdc, 0,0, NULL);
528 if ((hpen = CreatePen (PS_SOLID, 0, GetSysColor(COLOR_3DHILIGHT))) != NULL) {
529 SelectObject (ps.hdc, (LPVOID)hpen);
530 LineTo (ps.hdc, rect.right, 0);
531 DeleteObject (hpen);
532 }
533 MoveToEx(ps.hdc, 0, 1, NULL);
534 if ((hpen = CreatePen (PS_SOLID, 0, GetSysColor(COLOR_3DLIGHT))) != NULL) {
535 SelectObject (ps.hdc, (LPVOID)hpen);
536 LineTo (ps.hdc, rect.right, rect.bottom);
537 DeleteObject (hpen);
538 }
539
540 MoveToEx(ps.hdc, 0, rect.bottom-1, NULL);
541 if ((hpen = CreatePen (PS_SOLID, 0, GetSysColor(COLOR_3DSHADOW))) != NULL) {
542 SelectObject (ps.hdc, (LPVOID)hpen);
543 LineTo (ps.hdc, rect.right, rect.bottom-1);
544 DeleteObject (hpen);
545 }
546 MoveToEx(ps.hdc, 0, rect.bottom, NULL);
547 if ((hpen = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_3DDKSHADOW))) != NULL) {
548 SelectObject (ps.hdc, (LPVOID)hpen);
549 LineTo (ps.hdc, rect.right, rect.bottom);
550 DeleteObject (hpen);
551 }
552
553 EndPaint (hwnd, &ps);
554 return 0;
555
556 case WM_LBUTTONDOWN:
557 last_mouse_pos.x = LOWORD (lparam);
558 last_mouse_pos.y = HIWORD (lparam);
559 ClientToScreen (hwnd, &last_mouse_pos);
560 SetCapture (hwnd);
561 return 0;
562
563 case WM_LBUTTONUP:
564 ReleaseCapture ();
565 return 0;
566
567 case WM_MOUSEMOVE:
568 if (wparam == MK_LBUTTON) {
569 struct km_info_s *kmi;
570 POINT p;
571 RECT r;
572
573 kmi = (struct km_info_s *)GetWindowLong (hwnd, GWL_USERDATA);
574 if (kmi == NULL)
575 break;
576
577 /* Calculate mouse movement */
578 p.x = LOWORD(lparam);
579 p.y = HIWORD(lparam);
580 ClientToScreen (hwnd, &p);
581
582 GetWindowRect (hwnd, &r);
583 r.top += (short)(p.y - last_mouse_pos.y);
584 r.bottom += (short)(p.y - last_mouse_pos.y);
585
586 last_mouse_pos.y = p.y;
587
588 /* Apply mouse movement to window. Beware the MoveWindow is relaive
589 to parent NOT screen */
590 MapWindowPoints (NULL, GetParent(hwnd), (POINT*)&r, 2);
591 kmi->ypos_sep = r.top;
592 kmi->ypercent_sep = 0; /* This forces do_resize_window to use abs. position */
593 do_resize_window (GetParent(hwnd), kmi);
594 return 0;
595 }
596 }
597
598 return DefWindowProc (hwnd, msg, wparam, lparam);
599 }
600
601
602 /* Register the separator window with @dlg as the parent window. */
603 static HWND
604 regist_sep_wnd (HWND dlg, struct km_info_s *kmi)
605 {
606 WNDCLASS wndclass;
607 HWND h;
608
609 wndclass.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
610 wndclass.lpfnWndProc = separator_wnd_proc;
611 wndclass.cbClsExtra = 0;
612 wndclass.cbWndExtra = sizeof (long);
613 wndclass.hInstance = glob_hinst;
614 wndclass.hIcon = NULL;
615 wndclass.hCursor = LoadCursor (NULL, IDC_SIZENS);
616 wndclass.hbrBackground = (HBRUSH) GetStockObject (LTGRAY_BRUSH);
617 wndclass.lpszMenuName = 0;
618 wndclass.lpszClassName = WINDOWCLASS_SEPARATOR_CHILD;
619 RegisterClass (&wndclass);
620
621 h = CreateWindowEx (WS_EX_WINDOWEDGE, WINDOWCLASS_SEPARATOR_CHILD, NULL,
622 WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE,
623 0, 400, 2000, 5, dlg, (HMENU) 0, glob_hinst, kmi);
624 ShowWindow (h, SW_SHOW);
625 return h;
626 }
627
628
629 #define enable_button(hwnd, cid) \
630 SendMessage ((hwnd), TB_ENABLEBUTTON, (cid), MAKELONG (key_selected, 0))
631
632
633 /* Interactive modification of the dialog item which depend if an item
634 is selected or not and what kind of item. @lv is the list view with
635 the items. */
636 void
637 update_ui_items (HWND hwnd, listview_ctrl_t lv)
638 {
639 HWND hwnd_child;
640 HMENU hmenu;
641 int key_selected = 0;
642 int key_has_sec = 0;
643 int key_inv = 0;
644 int mult_resids[] = {ID_KEYMISC_PROPS, ID_KEYMISC_SIGN, ID_KEYMISC_EDITKEY,
645 ID_KEYMISC_CHECKSIGS, ID_KEYMISC_REVCERT, 0};
646 int i, state=0;
647
648 /* Get some states */
649 key_selected = SendMessage (GetDlgItem (hwnd, IDC_KEYMISC_KEYLIST),
650 LVM_GETSELECTEDCOUNT, 0, 0)
651 ? TRUE : FALSE;
652 key_has_sec = FALSE;
653 if (key_selected) {
654 i = listview_get_curr_pos (lv);
655 key_has_sec = km_check_for_seckey (lv, i, NULL) ? TRUE : FALSE;
656 key_inv = km_get_key_status (lv, i) & KM_FLAG_REVOKED ||
657 km_get_key_status (lv, i) & KM_FLAG_EXPIRED;
658 }
659
660 /* Enable / disable toolbar buttons */
661 hwnd_child = GetDlgItem (hwnd, IDR_WINPT_KMTB);
662 enable_button (hwnd_child, ID_KEYMISC_DELETE);
663 enable_button (hwnd_child, ID_KEYMISC_PROPS);
664 enable_button (hwnd_child, ID_KEYMISC_SIGN);
665 enable_button (hwnd_child, ID_KEYMISC_EXPORT);
666
667 /* Enable / disable menu items */
668 state = key_selected? MF_ENABLED : MF_DISABLED|MF_GRAYED;
669 hmenu = GetMenu (hwnd);
670 set_menu_state (hmenu, ID_KEYMISC_EXPORT, state);
671 set_menu_state (hmenu, ID_KEYMISC_DELETE, state);
672 set_menu_state (hmenu, ID_KEYMISC_PROPS, state);
673 set_menu_state (hmenu, ID_KEYMISC_EDITKEY, state);
674 set_menu_state (hmenu, ID_KEYMISC_CHECKSIGS, state);
675 set_menu_state (hmenu, ID_KEYMISC_SIGN,
676 key_selected && !key_inv ? MF_ENABLED : MF_GRAYED);
677 set_menu_state (hmenu, ID_KEYMISC_EXPORT_PRIVKEY,
678 key_selected && key_has_sec? MF_ENABLED : MF_GRAYED);
679 set_menu_state (hmenu, ID_KEYMISC_REVCERT,
680 key_selected && key_has_sec? MF_ENABLED : MF_GRAYED);
681
682 /* Disable some menu items when multiple keys are selected. */
683 if (listview_count_items (lv, 1) > 1) {
684 for (i=0; mult_resids[i] != 0; i++)
685 set_menu_state (hmenu, mult_resids[i], MF_GRAYED);
686 }
687 }
688
689
690 /* Disable some context menu items when multiple keys are selected. */
691 static void
692 popup_multiple (HWND dlg, HMENU hm)
693 {
694 int resids[] = {
695 ID_KEYCTX_EDIT,
696 ID_KEYCTX_SIGN,
697 ID_KEYCTX_REV,
698 ID_KEYCTX_ENABLE,
699 ID_KEYCTX_DISABLE,
700 ID_KEYCTX_ADDKEY,
701 ID_KEYCTX_ADDPHOTO,
702 ID_KEYCTX_ADDUID,
703 ID_KEYCTX_ADDREV,
704 ID_KEYCTX_LISTSIGS,
705 ID_KEYCTX_MAXTRUST,
706 ID_KEYCTX_PROPS,
707 ID_KEYCTX_SENDMAIL,
708 0};
709 int i;
710 for (i=0; i < resids[i] != 0; i++)
711 set_menu_state (hm, resids[i], MF_GRAYED);
712 }
713
714
715 /* The items which are shown when GPG is in read-only mode. */
716 static void
717 popup_gpg_readonly (HWND dlg, HMENU hm)
718 {
719 int resids[] = {
720 ID_KEYCTX_PASTE,
721 ID_KEYCTX_EDIT,
722 ID_KEYCTX_SIGN,
723 ID_KEYCTX_REV,
724 ID_KEYCTX_DEL,
725 ID_KEYCTX_ENABLE,
726 ID_KEYCTX_DISABLE,
727 ID_KEYCTX_RECVFROM,
728 ID_KEYCTX_ADDKEY,
729 ID_KEYCTX_ADDPHOTO,
730 ID_KEYCTX_ADDUID,
731 ID_KEYCTX_ADDREV,
732 0
733 };
734 int i;
735
736 if (gpg_read_only == 0)
737 return;
738 for (i=0; resids[i] != 0; i++)
739 set_menu_state (hm, resids[i], MF_GRAYED);
740 }
741
742
743 /* Change the 'Edit' menu based on the current state. */
744 static void
745 change_edit_menu (listview_ctrl_t lv, HMENU hm, int id)
746 {
747 enum item { EDIT_MENU = 1 };
748 int no_sel;
749
750 if (id != EDIT_MENU)
751 return;
752
753 if (!clip_contains_pgpkey ())
754 set_menu_state (hm, ID_KEYMISC_PASTE, MF_GRAYED);
755 else
756 set_menu_state (hm, ID_KEYMISC_PASTE, MF_ENABLED);
757 no_sel = listview_get_curr_pos (lv) == -1? 1 : 0;
758 set_menu_state (hm, ID_KEYMISC_DELETE2, no_sel? MF_GRAYED: MF_ENABLED);
759 set_menu_state (hm, ID_KEYMISC_COPY, no_sel? MF_GRAYED : MF_ENABLED);
760 }
761
762
763
764 /* Show limited key menu entries when GPG is in read-only mode. */
765 static void
766 change_key_menu (HMENU hm, int id)
767 {
768 int key_resids[] = {
769 ID_KEYMISC_SIGN,
770 ID_KEYMISC_DELETE,
771 ID_KEYMISC_REVCERT,
772 ID_KEYMISC_IMPORT_HTTP,
773 ID_KEYMISC_IMPORT,
774 ID_KEYMISC_REFRESH_KEYS,
775 ID_KEYMISC_REBUILD,
776 ID_KEYMISC_KEYWIZARD,
777 ID_KEYMISC_CARDNEW,
778 ID_KEYMISC_NEWKEY,
779 0,
780 };
781 int edit_resids[] = {
782 ID_KEYMISC_PASTE,
783 ID_KEYMISC_OT,
784 ID_KEYMISC_EDITKEY,
785 0
786 };
787 int *resids;
788 int i;
789
790
791 if (gpg_read_only == 0)
792 return;
793 switch (id) {
794 case 0: return;
795 case 3: resids = key_resids; break;
796 case 1: resids = edit_resids;break;
797 default:resids = edit_resids; break;
798 }
799
800 for (i=0; resids[i] != 0; i++)
801 set_menu_state (hm, resids[i], MF_GRAYED);
802 }
803
804
805 /* Reload a single key in the cache. */
806 static void
807 update_key (listview_ctrl_t lv, int pos, const char *keyid, int keypair)
808 {
809 gpgme_key_t key;
810
811 keycache_update (0, keyid);
812 if (keypair)
813 keycache_update (1, keyid);
814
815 /* because we replaced the key item, we need to update the
816 address of the pointer in the ListView control. */
817 get_pubkey (keyid, &key);
818 keylist_upd_key (lv, pos, key);
819 }
820
821
822 /* Setup status bar for the main window @dlg. */
823 static HWND
824 setup_status_bar (HWND dlg, listview_ctrl_t lv)
825 {
826 HWND statbar;
827 RECT r;
828 int partpos[3];
829 int i;
830
831 GetClientRect (dlg, &r);
832 for (i=1; i <= 3; i++)
833 partpos[i-1] = r.right/3*i;
834 statbar = CreateStatusWindow (WS_CHILD | WS_VISIBLE | CCS_BOTTOM,
835 "status bar", dlg, KM_SEPARATOR_ID);
836
837 ShowWindow (statbar, SW_SHOW);
838 SendMessage (statbar, SB_SETPARTS, (WPARAM)3, (LPARAM)partpos);
839
840 update_default_key_str (statbar);
841 update_status_bar (statbar, lv);
842
843 return statbar;
844 }
845
846
847 /* Remove or add columns which depends on the state of @checked. */
848 void
849 modify_listview_columns (km_info_s *kmi, UINT m_uid, BOOL checked)
850 {
851 UINT resids[] = {
852 0,
853 ID_KEYMISC_VIEWKEYID,
854 ID_KEYMISC_VIEWTYPE,
855 0,
856 ID_KEYMISC_VIEWCIPHER,
857 0,
858 0,
859 ID_KEYMISC_VIEWCREAT,
860 -1
861 };
862 listview_column_s cols[] = {
863 {0, 240, (char *)_("User ID")},
864 {1, 78, (char *)_("Key ID")},
865 {2, 52, (char *)_("Type")},
866 {3, 66, (char *)_("Size")},
867 {4, 60, (char *)_("Cipher")},
868 {5, 66, (char *)_("Validity")},
869 {6, 58, (char *)_("Trust")},
870 {7, 72, (char *)_("Creation")},
871 {0, 0, NULL}
872 };
873 UINT pos;
874
875 for (pos=0; resids[pos] != -1; pos++) {
876 if (m_uid == resids[pos])
877 break;
878 }
879 if (!checked)
880 listview_del_column (kmi->lv, (int)pos);
881 else {
882 listview_add_column (kmi->lv, &cols[pos]);
883 keylist_upd_col (kmi->lv, pos);
884 }
885 }
886
887
888 /* Translate all menu strings. */
889 static void
890 translate_menu_strings (HWND dlg)
891 {
892 HMENU menu;
893
894 menu = LoadMenu (glob_hinst, (LPCSTR)IDR_WINPT_KEYMISC);
895 set_menu_text_bypos (menu, 0, _("File"));
896 set_menu_text_bypos (menu, 1, _("Edit"));
897 set_menu_text_bypos (menu, 2, _("View"));
898 set_menu_text_bypos (menu, 3, _("Key"));
899 set_menu_text_bypos (menu, 4, _("Groups"));
900
901 set_menu_text (menu, ID_KEYMISC_EDITKEY, _("Edit"));
902 set_menu_text (menu, ID_KEYMISC_MAIL, _("Send Mail..."));
903 set_menu_text (menu, ID_KEYMISC_OT, _("Ownertrust")); /* XXX */
904 set_menu_text (menu, ID_KEYMISC_COPY, _("&Copy\tCtrl+C"));
905 set_menu_text (menu, ID_KEYMISC_PASTE, _("&Paste\tCtrl+V"));
906 set_menu_text (menu, ID_KEYMISC_FIND, _("Search...\tCtrl+F"));
907 set_menu_text (menu, ID_KEYMISC_SELALL, _("Select All\tCtrl+A"));
908 set_menu_text (menu, ID_KEYMISC_QUIT, _("&Quit"));
909 set_menu_text (menu, ID_KEYMISC_UID, _("User ID"));
910 set_menu_text (menu, ID_KEYMISC_NEWKEY, _("&Expert"));
911 set_menu_text (menu, ID_KEYMISC_KEYWIZARD, _("&Normal"));
912 set_menu_text (menu, ID_KEYMISC_EDIT, _("Edit"));
913 set_menu_text (menu, ID_KEYMISC_SIGN, _("&Sign"));
914 set_menu_text (menu, ID_KEYMISC_DELETE, _("&Delete"));
915 set_menu_text (menu, ID_KEYMISC_DELETE2, _("&Delete"));
916 set_menu_text (menu, ID_KEYMISC_REVCERT, _("&Revoke Cert"));
917 set_menu_text (menu, ID_KEYMISC_CHECKSIGS, _("&List Signatures"));
918 set_menu_text (menu, ID_KEYMISC_TRUSTPATH, _("List Trust Path"));
919 set_menu_text (menu, ID_KEYMISC_EXPORT, _("&Export..."));
920 set_menu_text (menu, ID_KEYMISC_IMPORT, _("&Import..."));
921 set_menu_text (menu, ID_KEYMISC_PROPS, _("&Properties"));
922 set_menu_text (menu, ID_KEYMISC_GPGOPT, _("Options"));
923 set_menu_text (menu, ID_KEYMISC_GPGPREFS, _("Preferences"));
924 set_menu_text (menu, ID_KEYMISC_SENDRECV, _("Keyserver") );
925 set_menu_text (menu, ID_KEYMISC_EXPORT_PRIVKEY, _("E&xport Secret Key"));
926 set_menu_text (menu, ID_KEYMISC_RECACHE, _("Re&load Key Cache"));
927 set_menu_text (menu, ID_KEYMISC_REBUILD, _("R&everify Signatures"));
928 set_menu_text (menu, ID_KEYMISC_REFRESH_KEYS, _("Refresh &Keys (Keyserver)"));
929 set_menu_text (menu, ID_KEYMISC_INFO, _("Info") );
930 set_menu_text (menu, ID_KEYMISC_HELP, _("&Help"));
931
932 set_menu_text (menu, ID_KEYMISC_VIEWKEYID, _("Key ID"));
933 set_menu_text (menu, ID_KEYMISC_VIEWCIPHER, _("Cipher"));
934 set_menu_text (menu, ID_KEYMISC_VIEWTYPE, _("Type"));
935 set_menu_text (menu, ID_KEYMISC_VIEWCREAT, _("Creation"));
936
937 /* XXX: implement help code. */
938 set_menu_state (menu, ID_KEYMISC_HELP, MF_GRAYED);
939
940 SetMenu (dlg, menu);
941 }
942
943
944 /* Translate popup menu strings. */
945 static void
946 translate_popupmenu_strings (HMENU popup)
947 {
948 set_menu_text (popup, ID_KEYCTX_UID_COPY, _("Copy User ID to Clipboard"));
949 set_menu_text (popup, ID_KEYCTX_KEYID_COPY, _("Copy Key ID to Clipboard"));
950 set_menu_text (popup, ID_KEYCTX_FPR_COPY, _("Copy Fingerprint to Clipboard"));
951 set_menu_text (popup, ID_KEYCTX_KINFO_COPY, _("Copy Key Info to Clipboard"));
952 set_menu_text (popup, ID_KEYCTX_COPY, _("Copy Key to Clipboard"));
953 set_menu_text (popup, ID_KEYCTX_PASTE, _("Paste Key from Clipboard"));
954 set_menu_text (popup, ID_KEYCTX_RECVFROM, _("Refresh from Keyserver"));
955 set_menu_text (popup, ID_KEYCTX_MAXTRUST, _("Set Implicit &Trust"));
956 set_menu_text (popup, ID_KEYCTX_LISTSIGS, _("&List Signatures"));
957 set_menu_text (popup, ID_KEYCTX_PROPS, _("&Properties"));
958 set_menu_text (popup, ID_KEYCTX_EDIT, _("Key Edit"));
959 set_menu_text (popup, ID_KEYCTX_DEL, _("&Delete"));
960 set_menu_text (popup, ID_KEYCTX_REV, _("&Revoke Cert"));
961 set_menu_text (popup, ID_KEYCTX_SIGN, _("&Sign"));
962 set_menu_text (popup, ID_KEYCTX_ENABLE, _("&Enable"));
963 set_menu_text (popup, ID_KEYCTX_DISABLE, _("&Disable"));
964 set_menu_text (popup, ID_KEYCTX_RECVFROM, _("Re&fresh from Keyserver"));
965 set_menu_text (popup, ID_KEYCTX_SETPREFKS, _("Set preferred Keyserver URL"));
966 set_menu_text (popup, ID_KEYCTX_SENDMAIL, _("Send Key to Mail Recipient"));
967 set_menu_text (popup, ID_KEYCTX_SETDEFKEY, _("Set as Default Key"));
968
969 set_menu_text (popup, ID_KEYCTX_ADDKEY, _("Key..."));
970 set_menu_text (popup, ID_KEYCTX_ADDUID, _("User ID..."));
971 set_menu_text (popup, ID_KEYCTX_ADDPHOTO, _("Photo ID..."));
972 set_menu_text (popup, ID_KEYCTX_ADDREV, _("Revoker..."));
973
974 /* change popup texts */
975 set_menu_text_bypos (popup, 0, _("Key Attributes"));
976 set_menu_text_bypos (popup, 6, _("Add"));
977 set_menu_text_bypos (popup, 19, _("Send to Keyserver"));
978 }
979
980
981 /* Dialog box procedure for the Key Manager. */
982 BOOL CALLBACK
983 keymanager_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
984 {
985 struct km_info_s *kmi;
986 static int refresh_keys = 0;
987 INITCOMMONCONTROLSEX icex;
988 HWND kl;
989 HMENU hm;
990 gpg_keycache_t c;
991 gpgme_key_t key;
992 struct genkey_s genkey;
993 struct winpt_key_s k = {0};
994 struct URL_ctx_s *url;
995 refresh_cache_s rcs = {0};
996 char type[32], *name;
997 const char *t, *host;
998 WORD port = 0;
999 int l_idx = 0, i=0, rc;
1000
1001 if ((msg != WM_INITDIALOG)
1002 && ((kmi = (struct km_info_s*)GetWindowLong (dlg, GWL_USERDATA)) == NULL))
1003 return FALSE;
1004
1005 switch (msg) {
1006 case WM_INITDIALOG:
1007 kmi = new struct km_info_s;
1008 memset (kmi, 0, sizeof (struct km_info_s));
1009 kmi->lv_idx = -1;
1010 icex.dwSize = sizeof (INITCOMMONCONTROLSEX);
1011 icex.dwICC = ICC_BAR_CLASSES;
1012 InitCommonControlsEx (&icex);
1013 kmi->hwnd_sep = regist_sep_wnd (dlg, kmi);
1014 imagelist_load (dlg);
1015 translate_menu_strings (dlg);
1016 SetWindowText (dlg, _("Key Manager"));
1017
1018 if (keyring_check_last_access ())
1019 keycache_set_reload (1);
1020 if (keycache_get_reload ())
1021 keycache_reload (dlg);
1022 c = keycache_get_ctx (KEYCACHE_PUB);
1023 if (!c)
1024 BUG (NULL);
1025 kl = GetDlgItem (dlg, IDC_KEYMISC_KEYLIST);
1026 kmi->keylist_sortby = KEY_SORT_USERID;
1027 Header_SetImageList(ListView_GetHeader (kl), glob_imagelist);
1028 kmi->lv = keylist_load (GetDlgItem (dlg, IDC_KEYMISC_KEYLIST), c,
1029 NULL, KEYLIST_LIST, kmi->keylist_sortby);
1030 /* init subclassing for the listview */
1031 keylist_proc.dlg = dlg;
1032 keylist_proc.current = (WNDPROC)keylist_subclass_proc;
1033 keylist_proc.old = (WNDPROC)GetWindowLong(kl, GWL_WNDPROC);
1034 if (keylist_proc.old) {
1035 if( !SetWindowLong (kl, GWL_WNDPROC, (LONG)keylist_proc.current)) {
1036 msg_box (dlg, _("Could not set keylist window procedure."),
1037 _("Key Manager"), MB_ERR);
1038 BUG (NULL);
1039 }
1040 }
1041 kmi->statbar = setup_status_bar (dlg, kmi->lv);
1042 SetWindowLong (dlg, GWL_USERDATA, (LONG)kmi);
1043 kmi->toolbar = load_toolbar (dlg, kmi);
1044
1045 do_center_window (dlg, kmi);
1046 do_resize_window (dlg, kmi);
1047 update_ui_items (dlg, kmi->lv);
1048 restore_column_info (kmi->lv);
1049
1050 SetDlgItemText (dlg, IDC_KEYMISC_GTEXT, _("Groups"));
1051 SetClassLong (dlg, GCL_HICON, (LONG)LoadIcon (glob_hinst,
1052 (LPCTSTR)IDI_WINPT));
1053 SetForegroundWindow (dlg);
1054 force_foreground_window (dlg, 1000);
1055 return TRUE;
1056
1057 case WM_DESTROY:
1058 save_column_info (kmi->lv);
1059 if (kmi->lv) {
1060 keylist_delete (kmi->lv);
1061 kmi->lv = NULL;
1062 }
1063 imagelist_destroy ();
1064
1065 ltoa (kmi->pos_x, type, 10);
1066 set_reg_entry (HKEY_CURRENT_USER, "Software\\WinPT", "KM_Pos_X", type);
1067 ltoa (kmi->pos_y, type, 10);
1068 set_reg_entry (HKEY_CURRENT_USER, "Software\\WinPT", "KM_Pos_Y", type);
1069
1070 /* Remove runtime information. This should be the last action taken here. */
1071 delete kmi; kmi = NULL;
1072 SetWindowLong (dlg, GWL_USERDATA, 0);
1073 keycache_set_reload (refresh_keys);
1074 return FALSE;
1075
1076 case WM_MOVE:
1077 RECT r;
1078 GetWindowRect (dlg, &r);
1079 kmi->pos_x = r.left;
1080 kmi->pos_y = r.top;
1081 break;
1082
1083
1084 case WM_RBUTTONUP:
1085 do_create_minpopup (dlg);
1086 break;
1087
1088 case WM_NOTIFY:
1089 NMHDR *notify;
1090 POINT p;
1091 HMENU popup;
1092
1093 notify = (NMHDR *)lparam;
1094 if (!notify)
1095 break;
1096 switch (notify->code) {
1097 case TBN_QUERYDELETE:
1098 SetWindowLong (dlg, DWL_MSGRESULT, TRUE);
1099 return TRUE;
1100
1101 case TBN_QUERYINSERT:
1102 SetWindowLong (dlg, DWL_MSGRESULT, TRUE);
1103 return TRUE;
1104
1105 case TBN_GETBUTTONINFO:
1106 LPTBNOTIFY lpTbNotify;
1107 lpTbNotify = (LPTBNOTIFY)lparam;
1108 if (lpTbNotify->iItem < (sizeof(myb) / sizeof(mybuttons))) {
1109 lpTbNotify->tbButton.iBitmap = imagelist_getindex(myb[lpTbNotify->iItem].icon);
1110 lpTbNotify->tbButton.idCommand = myb[lpTbNotify->iItem].command;
1111 lpTbNotify->tbButton.fsState = TBSTATE_ENABLED;
1112 lpTbNotify->tbButton.fsStyle = TBSTYLE_BUTTON;
1113 lpTbNotify->tbButton.iString = 0;
1114 strncpy (lpTbNotify->pszText, myb[lpTbNotify->iItem].text, lpTbNotify->cchText);
1115 SetWindowLong(dlg, DWL_MSGRESULT, TRUE);
1116 }
1117 return TRUE;
1118
1119 case TBN_RESET: /* Restore last saved toolbar status */
1120 TBSAVEPARAMS tbsp;
1121
1122 tbsp.hkr = HKEY_CURRENT_USER;
1123 tbsp.pszSubKey = "Software\\WinPT";
1124 tbsp.pszValueName = "KM_toolbar";
1125 SendMessage (notify->hwndFrom, TB_SAVERESTORE, FALSE, (LPARAM)&tbsp);
1126 break;
1127
1128 case TBN_BEGINADJUST: /* User is about to change the toolbar. Save it */
1129 tbsp.hkr = HKEY_CURRENT_USER;
1130 tbsp.pszSubKey = "Software\\WinPT";
1131 tbsp.pszValueName = "KM_toolbar";
1132 SendMessage (notify->hwndFrom, TB_SAVERESTORE, TRUE, (LPARAM)&tbsp);
1133 break;
1134
1135 case TBN_ENDADJUST: /* User has finished customizing the toolbar. Save it. */
1136 tbsp.hkr = HKEY_CURRENT_USER;
1137 tbsp.pszSubKey = "Software\\WinPT";
1138 tbsp.pszValueName = "KM_toolbar";
1139 SendMessage (notify->hwndFrom, TB_SAVERESTORE, TRUE, (LPARAM)&tbsp);
1140 break;
1141
1142 case TTN_GETDISPINFO:
1143 LPTOOLTIPTEXT lpttt;
1144 lpttt = (LPTOOLTIPTEXT)lparam;
1145
1146 lpttt->hinst = NULL;
1147 switch (lpttt->hdr.idFrom) {
1148 case ID_KEYMISC_DELETE:
1149 lpttt->lpszText = (char *)_("Delete key from keyring");
1150 break;
1151
1152 case ID_KEYMISC_PROPS:
1153 lpttt->lpszText = (char *)_("Show key properties");
1154 break;
1155
1156 case ID_KEYMISC_SIGN:
1157 lpttt->lpszText = (char *)_("Sign key");
1158 break;
1159
1160 case ID_KEYMISC_IMPORT:
1161 lpttt->lpszText = (char *)_("Import key to keyring");
1162 break;
1163
1164 case ID_KEYMISC_EXPORT:
1165 lpttt->lpszText = (char *)_("Export key to a file");
1166 break;
1167 }
1168 return TRUE;
1169
1170 case LVN_ITEMCHANGED:
1171 if (((LPNMLISTVIEW)lparam)->uNewState) { /* item selected? */
1172 kmi->lv_idx = listview_get_curr_pos (kmi->lv);
1173 update_ui_items (dlg, kmi->lv);
1174 return TRUE;
1175 }
1176 break;
1177
1178 case NM_RCLICK:
1179 if (notify->idFrom == IDC_KEYMISC_KEYLIST) {
1180 l_idx =listview_get_curr_pos (kmi->lv);
1181 if (l_idx == -1)
1182 return TRUE; /* Popup only when a item was selected */
1183 do_check_cache (kmi->lv, dlg, kmi->statbar);
1184 GetCursorPos (&p);
1185 hm = LoadMenu (glob_hinst, MAKEINTRESOURCE (IDR_WINPT_KEYMISC_CTX));
1186 popup = GetSubMenu (hm, 0);
1187 translate_popupmenu_strings (popup);
1188
1189 if (km_check_for_seckey (kmi->lv, l_idx, &i))
1190 set_menu_state (popup, ID_KEYCTX_SETDEFKEY, MF_ENABLED);
1191 if (i == 0)
1192 set_menu_state (popup, ID_KEYCTX_MAXTRUST, MF_ENABLED);
1193 if (!km_check_for_seckey (kmi->lv, l_idx, NULL)) {
1194 set_menu_state (popup, ID_KEYCTX_REV, MF_DISABLED|MF_GRAYED);
1195 set_menu_state (popup, ID_KEYCTX_ADDKEY, MF_DISABLED|MF_GRAYED);
1196 set_menu_state (popup, ID_KEYCTX_ADDUID, MF_DISABLED|MF_GRAYED);
1197 set_menu_state (popup, ID_KEYCTX_ADDREV, MF_DISABLED|MF_GRAYED);
1198 set_menu_state (popup, ID_KEYCTX_ADDPHOTO, MF_DISABLED|MF_GRAYED );
1199 set_menu_state (popup, ID_KEYCTX_SETPREFKS, MF_DISABLED|MF_GRAYED);
1200 }
1201 else if (km_check_for_seckey (kmi->lv, l_idx, NULL) &&
1202 km_key_is_v3 (kmi->lv, l_idx)) {
1203 /* PGP 2 keys, version 3 have no no support for photo-id's,
1204 designated revokers and secondary keys. */
1205 set_menu_state (popup, ID_KEYCTX_ADDKEY, MF_DISABLED|MF_GRAYED);
1206 set_menu_state (popup, ID_KEYCTX_ADDREV, MF_DISABLED|MF_GRAYED);
1207 set_menu_state (popup, ID_KEYCTX_ADDPHOTO, MF_DISABLED|MF_GRAYED);
1208 }
1209 if (km_get_key_status( kmi->lv, l_idx ) & KM_FLAG_DISABLED)
1210 set_menu_state (popup, ID_KEYCTX_DISABLE, MF_DISABLED|MF_GRAYED);
1211 else
1212 set_menu_state (popup, ID_KEYCTX_ENABLE, MF_DISABLED|MF_GRAYED);
1213 if (km_get_key_status (kmi->lv, l_idx) & KM_FLAG_REVOKED ||
1214 km_get_key_status (kmi->lv, l_idx) & KM_FLAG_EXPIRED)
1215 set_menu_state (popup, ID_KEYCTX_SIGN, MF_DISABLED|MF_GRAYED);
1216 if (!clip_contains_pgpkey ())
1217 set_menu_state (popup, ID_KEYCTX_PASTE, MF_DISABLED|MF_GRAYED);
1218 if (mapi_init ())
1219 set_menu_state (popup, ID_KEYCTX_SENDMAIL, MF_DISABLED|MF_GRAYED);
1220 /* Override 'Default Keyserver' with the actual name. */
1221 host = kserver_get_hostname (0, -1, &port);
1222 set_menu_text (popup, ID_KEYCTX_KS_DEFAULT, host);
1223 popup_gpg_readonly (dlg, popup);
1224 if (listview_count_items (kmi->lv, 1) > 1)
1225 popup_multiple (dlg, popup);
1226 TrackPopupMenu (popup, TPM_RIGHTALIGN, p.x, p.y, 0, dlg, NULL);
1227 DestroyMenu (popup);
1228 DestroyMenu (hm);
1229 return TRUE;
1230 }
1231 break;
1232
1233 case LVN_COLUMNCLICK:
1234 if (notify->idFrom == IDC_KEYMISC_KEYLIST) {
1235 NMLISTVIEW *nft = (LPNMLISTVIEW) lparam;
1236 int sortby = 0;
1237 switch (nft->iSubItem) {
1238 case 0: sortby = KEY_SORT_USERID; break;
1239 case 1: sortby = KEY_SORT_KEYID; break;
1240 case 2: sortby = KEY_SORT_IS_SECRET; break;
1241 case 3: sortby = KEY_SORT_LEN; break;
1242 case 5: sortby = KEY_SORT_VALIDITY; break;
1243 case 6: sortby = KEY_SORT_OTRUST; break;
1244 case 7: sortby = KEY_SORT_CREATED; break;
1245 case 8: sortby = KEY_SORT_ALGO; break;
1246 default: return TRUE; //sortby = KEY_SORT_USERID; break;
1247 }
1248
1249 if ((kmi->keylist_sortby & ~KEYLIST_SORT_DESC) == sortby)
1250 kmi->keylist_sortby ^= KEYLIST_SORT_DESC;
1251 else
1252 kmi->keylist_sortby = sortby;
1253 keylist_sort (kmi->lv, kmi->keylist_sortby);
1254 return TRUE;
1255 }
1256 break;
1257 }
1258 break;
1259
1260 case WM_WINDOWPOSCHANGING:
1261 if (((WINDOWPOS*)lparam)->cx < 400)
1262 ((WINDOWPOS*)lparam)->cx = 400;
1263 if (((WINDOWPOS*)lparam)->cy < 200)
1264 ((WINDOWPOS*)lparam)->cy = 200;
1265 return TRUE;
1266
1267 case WM_SIZE:
1268 do_resize_window (dlg, kmi);
1269 return TRUE;
1270
1271 case WM_SYSCOMMAND:
1272 if (LOWORD (wparam) == SC_CLOSE)
1273 EndDialog (dlg, TRUE);
1274 return FALSE;
1275
1276 case WM_MENUSELECT:
1277 change_edit_menu (kmi->lv, (HMENU)lparam, LOWORD (wparam));
1278 change_key_menu ((HMENU)lparam, LOWORD (wparam));
1279 break;
1280
1281 case WM_INITMENUPOPUP:
1282 if ((UINT)LOWORD (lparam) == 3) {
1283 HMENU h = (HMENU)wparam;
1284 set_menu_text_bypos (h, 0, _("New"));
1285 }
1286 return FALSE;
1287
1288 case WM_COMMAND:
1289 /* Allow at least 'Exit' in such a case. */
1290 if (gnupg_access_keyring (1) && LOWORD (wparam) != ID_KEYMISC_QUIT) {
1291 msg_box (dlg, _("Could not access public keyring"),
1292 _("Key Manager"), MB_ERR);
1293 return FALSE;
1294 }
1295 do_check_cache (kmi->lv, dlg, kmi->statbar);
1296 switch( LOWORD (wparam)) {
1297 case ID_KEYMISC_QUIT:
1298 EndDialog (dlg, TRUE);
1299 return TRUE;
1300
1301 case ID_KEYMISC_MAIL:
1302 /* XXX
1303 DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_MAIL, GetDesktopWindow (),
1304 winpt_mail_proc, NULL);*/
1305 break;
1306
1307 case ID_KEYMISC_FIND:
1308 km_find_key (dlg, kmi->lv);
1309 break;
1310
1311 case ID_KEYMISC_DELETE:
1312 case ID_KEYMISC_DELETE2:
1313 if (!km_delete_keys (kmi->lv, dlg))
1314 update_status_bar (kmi->statbar, kmi->lv);
1315 return TRUE;
1316
1317 case ID_KEYMISC_SIGN:
1318 if (kmi->lv_idx == -1) {
1319 msg_box (dlg, _("Please select a key."),
1320 _("Key Manager"), MB_ERR);
1321 return TRUE;
1322 }
1323 if (km_check_key_status (kmi->lv, kmi->lv_idx))
1324 return TRUE;
1325 key = (gpgme_key_t)listview_get_item2 (kmi->lv, kmi->lv_idx);
1326 memset (&k, 0, sizeof (k));
1327 k.ctx = key;
1328 k.keyid = key->subkeys->keyid;
1329 dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_KEYSIGN, dlg,
1330 keysign_dlg_proc, (LPARAM)&k,
1331 _("Key Signing"), IDS_WINPT_KEYSIGN);
1332 if (k.update)
1333 update_key (kmi->lv, kmi->lv_idx, k.keyid, 0);
1334 return TRUE;
1335
1336 case ID_KEYMISC_REVCERT:
1337 if (kmi->lv_idx == -1) {
1338 msg_box (dlg, _("Please select a key."), _("Key Manager"), MB_ERR);
1339 return TRUE;
1340 }
1341 key = (gpgme_key_t)listview_get_item2 (kmi->lv, kmi->lv_idx);
1342 if (!key)
1343 BUG (NULL);
1344 if (!km_check_for_seckey (kmi->lv, kmi->lv_idx, NULL)) {
1345 msg_box (dlg, _("There is no secret key available!"),
1346 _("Key Manager"), MB_ERR);
1347 return TRUE;
1348 }
1349
1350 {
1351 char state[64];
1352 listview_get_item_text (kmi->lv, kmi->lv_idx, 5,
1353 state, sizeof (state) -1);
1354 if (strchr (state, 'R' )) {
1355 msg_box (dlg, _("Key already revoked!"),
1356 _("Key Manager"), MB_INFO);
1357 return TRUE;
1358 }
1359 }
1360
1361 memset (&k, 0, sizeof (k));
1362 k.key_pair = 1;
1363 k.keyid = key->subkeys->keyid+8;
1364 k.is_protected = km_check_if_protected (kmi->lv, kmi->lv_idx);
1365 dialog_box_param(glob_hinst, (LPCSTR)IDD_WINPT_KEYREVOKE, dlg,
1366 key_revoke_dlg_proc, (LPARAM)&k,
1367 _("Key Revocation Cert"), IDS_WINPT_KEYREVOKE);
1368 return TRUE;
1369
1370 case ID_KEYMISC_TRUSTPATH:
1371 if (kmi->lv_idx == -1) {
1372 msg_box (dlg, _("Please select a key."), _("Key Manager"), MB_ERR);
1373 return TRUE;
1374 }
1375 key = (gpgme_key_t)listview_get_item2 (kmi->lv, kmi->lv_idx);
1376 if (km_check_for_seckey (kmi->lv, kmi->lv_idx, NULL)) {
1377 msg_box (dlg, _("It does not make any sense with a key pair!"),
1378 _("Key Manager"), MB_ERR);
1379 return TRUE;
1380 }
1381 memset (&k, 0, sizeof (k));
1382 k.keyid = key->subkeys->keyid+8;
1383 k.uid = key->uids->uid;
1384 dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_KEYTRUST, dlg,
1385 keytrust_dlg_proc, (LPARAM)&k,
1386 _("List Trust Path"), IDS_WINPT_KEYTRUST);
1387 return TRUE;
1388
1389 case ID_KEYMISC_CHECKSIGS:
1390 if (kmi->lv_idx == -1) {
1391 msg_box (dlg, _("Please select a key."), _("Key Manager"), MB_ERR);
1392 return TRUE;
1393 }
1394 key = (gpgme_key_t)listview_get_item2 (kmi->lv, kmi->lv_idx);
1395 if (!key)
1396 BUG (NULL);
1397 memset (&k, 0, sizeof (k));
1398 k.keyid = key->subkeys->keyid+8;
1399 k.uid = key->uids->uid;
1400 k.ctx = (gpgme_key_t)listview_get_item2 (kmi->lv, kmi->lv_idx);
1401 dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_KEYSIG, dlg,
1402 keysig_dlg_proc, (LPARAM)&k,
1403 _("Key Signature List" ), IDS_WINPT_KEYSIG);
1404 return TRUE;
1405
1406 case ID_KEYMISC_PROPS:
1407 if (kmi->lv_idx == -1) {
1408 msg_box( dlg, _("Please select a key."), _("Key Manager"), MB_ERR );
1409 return TRUE;
1410 }
1411 key = (gpgme_key_t)listview_get_item2 (kmi->lv, kmi->lv_idx);
1412 if (!key)
1413 BUG (NULL);
1414 memset (&k, 0, sizeof (k));
1415 k.key_pair = km_check_for_seckey (kmi->lv, kmi->lv_idx, NULL)? 1 : 0;
1416 k.keyid = key->subkeys->keyid+8;
1417 k.callback.ctl = kmi->lv;
1418 k.callback.idx = kmi->lv_idx;
1419 k.is_v3 = km_key_is_v3 (kmi->lv, kmi->lv_idx);
1420 dialog_box_param( glob_hinst, (LPCSTR)IDD_WINPT_KEYPROPS, dlg,
1421 keyprops_dlg_proc, (LPARAM)&k,
1422 _("Key Properties"), IDS_WINPT_KEYPROPS );
1423 if (k.callback.new_val != 0) {
1424 t = get_key_trust_str (k.callback.new_val);
1425 listview_add_sub_item (kmi->lv, kmi->lv_idx, 6, t);
1426 }
1427 return TRUE;
1428
1429 case ID_KEYMISC_RECACHE:
1430 /* If there is already a reload request,
1431 don't bother the user with a message. */
1432 if (keycache_get_reload() == 1)
1433 l_idx = IDYES;
1434 else {
1435 char inf[256];
1436 _snprintf (inf, sizeof (inf) -1,
1437 _("This is only useful when the keyring has been "
1438 "modified (sign a key...).\n"
1439 "Do you really want to reload the keycache?"));
1440 l_idx = msg_box (dlg, inf, _("Key Manager"), MB_YESNO);
1441 }
1442 if (l_idx == IDYES) {
1443 rcs.kr_reload = rcs.kr_update = 1;
1444 rcs.tr_update = 0;
1445 DialogBoxParam (glob_hinst, (LPCSTR)IDD_WINPT_KEYCACHE, dlg,
1446 keycache_dlg_proc, (LPARAM)&rcs);
1447 c = keycache_get_ctx (1);
1448 if (!c)
1449 BUG (dlg);
1450 keylist_reload (kmi->lv, c, KEYLIST_LIST, KEY_SORT_USERID);
1451 refresh_keys = 0;
1452 }
1453 return TRUE;
1454
1455 case ID_KEYMISC_REBUILD:
1456 name = NULL;
1457 gpg_rebuild_cache (&name);
1458 if (name != NULL) {
1459 char *line = strchr (name, '\n');
1460 show_msg (dlg, 2000, line? name + (line-name)+1 : name);
1461 safe_free (name);
1462 }
1463 return TRUE;
1464
1465 case ID_KEYMISC_NEWKEY:
1466 memset (&genkey, 0, sizeof (genkey));
1467 dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_KEYGEN, dlg,
1468 keygen_dlg_proc, (LPARAM)&genkey, _("Key Generation"),
1469 IDS_WINPT_KEYGEN);
1470 if (genkey.newkey != NULL) {
1471 keylist_add_key (kmi->lv, KEYLIST_LIST, genkey.newkey);
1472 keylist_sort (kmi->lv, KEY_SORT_USERID);
1473 }
1474 return TRUE;
1475
1476 case ID_KEYMISC_CARDNEW:
1477 if (!scard_support) {
1478 msg_box (dlg, _("Smart Card support is not available."),
1479 _("Key Manager"), MB_INFO);
1480 return TRUE;
1481 }
1482 dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_CARD_KEYGEN, dlg,
1483 card_keygen_dlg_proc, 0, _("Card Key Generation"),
1484 IDS_WINPT_CARD_KEYGEN);
1485 /* XXX: use new code */
1486 if (keycache_get_reload ())
1487 send_cmd_id (dlg, ID_KEYMISC_RECACHE);
1488 return TRUE;
1489
1490 case ID_KEYMISC_KEYWIZARD:
1491 memset (&genkey, 0, sizeof (genkey));
1492 dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_KEYWIZARD, dlg,
1493 keygen_wizard_dlg_proc, (LPARAM)&genkey,
1494 _("Key Generation Wizard"),
1495 IDS_WINPT_KEYWIZARD);
1496 if (genkey.newkey != NULL) {
1497 keylist_add_key (kmi->lv, KEYLIST_LIST, genkey.newkey);
1498 keylist_sort (kmi->lv, KEY_SORT_USERID);
1499 }
1500 return TRUE;
1501
1502 case ID_KEYMISC_SENDRECV:
1503 memset (&genkey, 0, sizeof (genkey));
1504 dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_KEYSERVER, dlg,
1505 keyserver_dlg_proc, (LPARAM)&genkey, _("Keyserver Access"),
1506 IDS_WINPT_KEYSERVER);
1507 if (genkey.newkey != NULL) {
1508 keylist_add_key (kmi->lv, KEYLIST_LIST, genkey.newkey);
1509 keylist_sort (kmi->lv, KEY_SORT_USERID);
1510 }
1511 return TRUE;
1512
1513 case ID_KEYMISC_GPGPREFS:
1514 dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_GPGPREFS, dlg,
1515 gpgprefs_dlg_proc, 0, _("GnuPG Preferences"),
1516 IDS_WINPT_GPGPREFS);
1517 return TRUE;
1518
1519 case ID_KEYMISC_GPGOPT:
1520 dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_GPGOPT, dlg,
1521 gpgopt_dlg_proc, 0, _("GnuPG Options"),
1522 IDS_WINPT_GPGOPT);
1523 return TRUE;
1524
1525 case ID_KEYMISC_IMPORT:
1526 t = get_fileopen_dlg (dlg, _("Choose Name of the Key File"),
1527 NULL, NULL);
1528 if (t)
1529 km_file_import (dlg, t);
1530 return TRUE;
1531
1532 case ID_KEYMISC_IMPORT_HTTP:
1533 url = (struct URL_ctx_s*)get_http_file_dlg (dlg);
1534 if (url->cancel == 0)
1535 km_http_import (dlg, url->url);
1536 delete url; url=NULL;
1537 break;
1538
1539 case ID_KEYMISC_EXPORT:
1540 if (kmi->lv_idx == -1) {
1541 msg_box (dlg, _("Please select a key."),
1542 _("Key Manager"), MB_ERR);
1543 return TRUE;
1544 }
1545 if (listview_count_items (kmi->lv, 1) > 1)
1546 name = m_strdup ("Exported_GPG_Keys.asc");
1547 else {
1548 key = (gpgme_key_t)listview_get_item2 (kmi->lv, kmi->lv_idx);
1549 name = km_gen_export_filename (key->subkeys->keyid+8, 0);
1550 }
1551 t = get_filesave_dlg (dlg, _("Choose Name for Key File"), NULL, name);
1552 free_if_alloc (name);
1553 if (t == NULL)
1554 return TRUE;
1555 km_file_export (dlg, kmi->lv, t);
1556 return TRUE;
1557
1558 case ID_KEYMISC_EXPORT_PRIVKEY:
1559 if (kmi->lv_idx == -1) {
1560 msg_box (dlg, _("Please select a key."), _("Key Manager"), MB_ERR);
1561 return TRUE;
1562 }
1563 if( !km_check_for_seckey( kmi->lv, kmi->lv_idx, NULL ) ) {
1564 msg_box (dlg, _("There is no corresponding secret key for this key."),
1565 _("Key Manager"), MB_ERR);
1566 return TRUE;
1567 }
1568 if (listview_count_items (kmi->lv, 1) > 1) {
1569 msg_box (dlg, _("You can only export one secret key."),
1570 _("Key Manager"), MB_ERR);
1571 return TRUE;
1572 }
1573 i = msg_box (dlg,
1574 _("This operation will export your *SECRET* key!\n\n"
1575 "Never send this key to ANYONE, it should be available\n"
1576 "ONLY on your machine and you may use this function\n"
1577 "to copy the key to a safe place.\n\n"
1578 "Do you really want to export the key?"),
1579 _("WARNING"), MB_INFO|MB_YESNO);
1580 if (i == IDYES) {
1581 key = (gpgme_key_t)listview_get_item2 (kmi->lv, kmi->lv_idx);
1582 if (!key)
1583 BUG (NULL);
1584 name = km_gen_export_filename (key->subkeys->keyid+8, 1);
1585 t = get_filesave_dlg (dlg, _("Choose Name for Key File"), NULL, name);
1586 if (t != NULL)
1587 km_privkey_export (dlg, kmi->lv, t);
1588 }
1589 return TRUE;
1590
1591 case ID_KEYMISC_INFO:
1592 dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_ABOUT, glob_hwnd,
1593 about_winpt_dlg_proc, 0, _("About WinPT"),
1594 IDS_WINPT_ABOUT);
1595 break;
1596
1597 case ID_KEYMISC_HELP:
1598 ShellExecute (dlg, "open", "winpt.chm", NULL, NULL, SW_SHOW);
1599 break;
1600
1601 case ID_KEYMISC_OT:
1602 dialog_box_param (glob_hinst, (LPCTSTR)IDD_WINPT_OWNERTRUST,
1603 glob_hwnd, ownertrust_dlg_proc, 0,
1604 _("Ownertrust"), IDS_WINPT_OWNERTRUST);
1605 break;
1606
1607 case ID_KEYMISC_EDITKEY:
1608 if (kmi->lv_idx == -1)
1609 break;
1610 key = (gpgme_key_t)listview_get_item2 (kmi->lv, kmi->lv_idx);
1611 if (!key)
1612 BUG (NULL);
1613 /* XXX: pub/crd = secret key does not work */
1614 memset (&k, 0, sizeof (k));
1615 k.is_protected = km_check_if_protected (kmi->lv, kmi->lv_idx);
1616 k.key_pair = km_check_for_seckey (kmi->lv, kmi->lv_idx, NULL);
1617 k.keyid = key->subkeys->keyid+8;
1618 k.is_v3 = km_key_is_v3 (kmi->lv, kmi->lv_idx);
1619 k.flags = km_get_key_status (kmi->lv, kmi->lv_idx);
1620 dialog_box_param (glob_hinst, (LPCTSTR)IDD_WINPT_KEYEDIT, dlg,
1621 keyedit_main_dlg_proc, (LPARAM)&k,
1622 _("Key Edit"), IDS_KEYCTX_EDIT);
1623 if (k.update)
1624 update_key (kmi->lv, kmi->lv_idx, k.keyid, 1);
1625 break;
1626
1627 case ID_KEYMISC_COPY:
1628 km_clip_export (dlg, kmi->lv);
1629 break;
1630
1631 case ID_KEYMISC_SELALL:
1632 listview_select_all (kmi->lv);
1633 break;
1634
1635 case ID_KEYMISC_PASTE:
1636 km_clip_import (dlg);
1637 break;
1638
1639 case ID_KEYCTX_SETPREFKS:
1640 key = (gpgme_key_t)listview_get_item2 (kmi->lv, kmi->lv_idx);
1641 if (!key)
1642 BUG (NULL);
1643 memset (&k, 0, sizeof (k));
1644 k.keyid = key->subkeys->keyid+8;
1645 keyedit_set_pref_keyserver (&k, dlg);
1646 break;
1647
1648 case ID_KEYMISC_REFRESH_KEYS:
1649 if (listview_count_items (kmi->lv, 1) == 0) {
1650 msg_box (dlg, _("No key was selected, select all by default."),
1651 _("Key Manager"), MB_INFO);
1652 listview_select_all (kmi->lv);
1653 }
1654 km_refresh_from_keyserver (kmi->lv, dlg);
1655 break;
1656
1657 /** Context menu **/
1658 case ID_KEYCTX_EDIT:
1659 send_cmd_id( dlg, ID_KEYMISC_EDITKEY );
1660 break;
1661
1662 case ID_KEYCTX_PROPS:
1663 send_cmd_id( dlg, ID_KEYMISC_PROPS );
1664 break;
1665
1666 case ID_KEYCTX_UIDS:
1667 send_cmd_id( dlg, ID_KEYMISC_UID );
1668 break;
1669
1670 case ID_KEYCTX_SIGN:
1671 send_cmd_id( dlg, ID_KEYMISC_SIGN );
1672 break;
1673
1674 case ID_KEYCTX_DEL:
1675 send_cmd_id (dlg, ID_KEYMISC_DELETE);
1676 break;
1677
1678 case ID_KEYCTX_REV:
1679 send_cmd_id( dlg, ID_KEYMISC_REVCERT );
1680 break;
1681
1682 case ID_KEYCTX_SENDMAIL:
1683 km_send_to_mail_recipient (kmi->lv, dlg);
1684 break;
1685
1686 case ID_KEYCTX_KS_DEFAULT:
1687 host = kserver_get_hostname (0, -1, &port);
1688 km_send_to_keyserver (kmi->lv, dlg, host, port);
1689 break;
1690
1691 case ID_KEYCTX_ADDKEY:
1692 key = (gpgme_key_t)listview_get_item2 (kmi->lv, kmi->lv_idx);
1693 if (!key)
1694 BUG (NULL);
1695 memset (&k, 0, sizeof (k));
1696 k.key_pair = km_check_for_seckey (kmi->lv, kmi->lv_idx, NULL);
1697 k.is_protected = km_check_if_protected (kmi->lv, kmi->lv_idx);
1698 k.keyid = key->subkeys->keyid+8;
1699 keyedit_add_subkey (&k, dlg, NULL);
1700 if (k.update)
1701 update_key (kmi->lv, kmi->lv_idx, k.keyid, 1);
1702 break;
1703
1704 case ID_KEYCTX_ADDUID:
1705 key = (gpgme_key_t)listview_get_item2 (kmi->lv, kmi->lv_idx);
1706 if (!key)
1707 BUG (NULL);
1708 memset (&k, 0, sizeof (k));
1709 k.key_pair = km_check_for_seckey (kmi->lv, kmi->lv_idx, NULL);
1710 k.is_protected = km_check_if_protected (kmi->lv, kmi->lv_idx);
1711 k.keyid = key->subkeys->keyid+8;
1712 keyedit_add_userid (&k, dlg, NULL);
1713 if (k.update)
1714 update_key (kmi->lv, kmi->lv_idx, k.keyid, 1);
1715 break;
1716
1717 case ID_KEYCTX_ADDREV:
1718 key = (gpgme_key_t)listview_get_item2 (kmi->lv, kmi->lv_idx);
1719 if (!key)
1720 BUG (NULL);
1721 memset (&k, 0, sizeof (k));
1722 k.keyid = key->subkeys->keyid+8;
1723 k.is_protected = km_check_if_protected (kmi->lv, kmi->lv_idx);
1724 k.key_pair = km_check_for_seckey (kmi->lv, kmi->lv_idx, NULL);
1725 keyedit_add_revoker (&k, dlg);
1726 if (k.update)
1727 update_key (kmi->lv, kmi->lv_idx, k.keyid, 1);
1728 break;
1729
1730 case ID_KEYCTX_ADDPHOTO:
1731 key = (gpgme_key_t)listview_get_item2 (kmi->lv, kmi->lv_idx);
1732 if (!key)
1733 BUG (NULL);
1734 memset (&k, 0, sizeof (k));
1735 k.keyid = key->subkeys->keyid+8;
1736 k.is_protected = km_check_if_protected (kmi->lv, kmi->lv_idx);
1737 k.key_pair = km_check_for_seckey (kmi->lv, kmi->lv_idx, NULL);
1738 keyedit_add_photo (&k, dlg);
1739 if (k.update)
1740 update_key (kmi->lv, kmi->lv_idx, k.keyid, 1);
1741 break;
1742
1743 case ID_KEYCTX_KS_NL:
1744 case ID_KEYCTX_KS_PL:
1745 case ID_KEYCTX_KS_AT:
1746 case ID_KEYCTX_KS_DE:
1747 case ID_KEYCTX_KS_DK:
1748 case ID_KEYCTX_KS_CZ:
1749 case ID_KEYCTX_KS_ES:
1750 case ID_KEYCTX_KS_UK:
1751 host = kserver_get_hostname (LOWORD (wparam) - 40107, 0, &port);
1752 km_send_to_keyserver (kmi->lv, dlg, host, port);
1753 break;
1754
1755 case ID_KEYCTX_RECVFROM:
1756 km_refresh_from_keyserver (kmi->lv, dlg);
1757 break;
1758
1759 case ID_KEYCTX_UID_COPY:
1760 /* XXX: add generic function to support multiple selection
1761 with a callback */
1762 key = (gpgme_key_t)listview_get_item2 (kmi->lv, kmi->lv_idx);
1763 name = utf8_to_wincp2 (key->uids->uid);
1764 set_clip_text (NULL, name, strlen (name));
1765 safe_free (name);
1766 break;
1767
1768 case ID_KEYCTX_KEYID_COPY:
1769 key = (gpgme_key_t)listview_get_item2 (kmi->lv, kmi->lv_idx);
1770 set_clip_text (NULL, key->subkeys->keyid+8,
1771 strlen (key->subkeys->keyid+8));
1772 break;
1773
1774 case ID_KEYCTX_FPR_COPY:
1775 key = (gpgme_key_t) listview_get_item2 (kmi->lv, kmi->lv_idx);
1776 //t = get_key_fpr (key);
1777 t = key->subkeys->fpr;
1778 set_clip_text (NULL, t? t : "", t? strlen (t): 0);
1779 break;
1780
1781 case ID_KEYCTX_KINFO_COPY:
1782 key = (gpgme_key_t) listview_get_item2 (kmi->lv, kmi->lv_idx);
1783 if (!key)
1784 BUG (NULL);
1785 km_set_clip_info (key->subkeys->keyid+8);
1786 break;
1787
1788 case ID_KEYCTX_COPY:
1789 km_clip_export (dlg, kmi->lv);
1790 break;
1791
1792 case ID_KEYCTX_PASTE:
1793 km_clip_import (dlg);
1794 break;
1795
1796 case ID_KEYCTX_DISABLE:
1797 case ID_KEYCTX_ENABLE:
1798 i = LOWORD (wparam) == ID_KEYCTX_ENABLE? 1 : 0;
1799 key = (gpgme_key_t)listview_get_item2 (kmi->lv, kmi->lv_idx);
1800 if (!key)
1801 BUG (NULL);
1802 rc = km_enable_disable_key (kmi->lv, dlg, kmi->lv_idx, i);
1803 if (!rc)
1804 update_key (kmi->lv, kmi->lv_idx, key->subkeys->keyid+8, 0);
1805 /* XXX: switching a key from disabled -> enabled. does not
1806 change the validity field in the KM. */
1807 break;
1808
1809 case ID_KEYCTX_LISTSIGS:
1810 send_cmd_id (dlg, ID_KEYMISC_CHECKSIGS);
1811 break;
1812
1813 case ID_KEYCTX_MAXTRUST:
1814 key = (gpgme_key_t)listview_get_item2 (kmi->lv, kmi->lv_idx);
1815 if (!key)
1816 BUG (NULL);
1817 rc = km_set_implicit_trust (dlg, kmi->lv, kmi->lv_idx);
1818 if (!rc)
1819 update_key (kmi->lv, kmi->lv_idx, key->subkeys->keyid+8, 0);
1820 break;
1821
1822 case ID_KEYCTX_SETDEFKEY:
1823 if (!km_check_key_status (kmi->lv, kmi->lv_idx)) {
1824 key = (gpgme_key_t)listview_get_item2 (kmi->lv, kmi->lv_idx);
1825 rc = set_gnupg_default_key (key->subkeys->keyid+8);
1826 if (rc)
1827 msg_box (dlg, winpt_strerror (rc), _("Key Manager"), MB_ERR);
1828 update_default_key_str (kmi->statbar);
1829 }
1830 break;
1831
1832 case ID_KEYMISC_VIEWKEYID:
1833 case ID_KEYMISC_VIEWCIPHER:
1834 case ID_KEYMISC_VIEWTYPE:
1835 case ID_KEYMISC_VIEWCREAT:
1836 DWORD n;
1837
1838 hm = GetMenu (dlg);
1839 n = get_menu_state (hm, LOWORD (wparam));
1840 set_menu_state (hm, LOWORD (wparam),
1841 n & MFS_CHECKED? MFS_UNCHECKED : MFS_CHECKED);
1842 modify_listview_columns (kmi, LOWORD (wparam), !(n & MFS_CHECKED));
1843 break;
1844
1845 case ID_GROUP_NEW:
1846 case ID_GROUP_PASTE:
1847 case ID_GROUP_DELETE:
1848 /* XXX: Implement group manager. */
1849 return TRUE;
1850 }
1851
1852 break;
1853 }
1854
1855 return FALSE;
1856 }

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26