rx: Remove RX_CALL_BUSY
[openafs.git] / src / WINNT / afsusrmgr / browse.cpp
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  *
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 extern "C" {
11 #include <afs/param.h>
12 #include <afs/stds.h>
13 }
14
15 #include "TaAfsUsrMgr.h"
16 #include "browse.h"
17 #include "usr_col.h"
18
19
20 /*
21  * DEFINITIONS ________________________________________________________________
22  *
23  */
24
25 #define ID_SEARCH_TIMER     0
26
27 #define msecSEARCH_TIMER  650
28
29 static struct
30    {
31    DWORD dwTickLastType;
32    } l;
33
34
35 /*
36  * PROTOTYPES _________________________________________________________________
37  *
38  */
39
40 BOOL CALLBACK Browse_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp);
41 void Browse_OnInitDialog (HWND hDlg);
42 void Browse_OnOK (HWND hDlg);
43 void Browse_OnEndTask_EnumObjects (HWND hDlg, LPTASKPACKET ptp);
44 void Browse_OnEndTask_Translate (HWND hDlg, LPTASKPACKET ptp);
45 void Browse_OnSelect (HWND hDlg);
46 void Browse_UpdateDialog (HWND hDlg);
47 void Browse_Enable (HWND hDlg, BOOL fEnable);
48 ASOBJTYPE Browse_GetSelectedType (HWND hDlg);
49
50
51 /*
52  * ROUTINES ___________________________________________________________________
53  *
54  */
55
56 BOOL ShowBrowseDialog (LPBROWSE_PARAMS lpp)
57 {
58    int nTypesToShow = 0;
59    if (lpp->TypeToShow & TYPE_USER)
60       ++nTypesToShow;
61    if (lpp->TypeToShow & TYPE_GROUP)
62       ++nTypesToShow;
63    lpp->fQuerying = FALSE;
64
65    int idd = (nTypesToShow == 1) ? IDD_BROWSE : (lpp->idsCheck) ? IDD_BROWSE_BOTH : IDD_BROWSE_COMBO;
66
67    if (ModalDialogParam (idd, lpp->hParent, (DLGPROC)Browse_DlgProc, (LPARAM)lpp) != IDOK)
68       return FALSE;
69
70    if (!lpp->pObjectsSelected)
71       return FALSE;
72
73    return TRUE;
74 }
75
76
77 BOOL CALLBACK Browse_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
78 {
79    LPBROWSE_PARAMS lpp;
80    if ((lpp = (LPBROWSE_PARAMS)GetWindowLongPtr (hDlg, DWLP_USER)) != NULL)
81       {
82       if (AfsAppLib_HandleHelp (lpp->iddForHelp, hDlg, msg, wp, lp))
83          return FALSE;
84       }
85
86    switch (msg)
87       {
88       case WM_INITDIALOG:
89          SetWindowLongPtr (hDlg, DWLP_USER, lp);
90          Browse_OnInitDialog (hDlg);
91          l.dwTickLastType = 0;
92          break;
93
94       case WM_ENDTASK:
95          LPTASKPACKET ptp;
96          if ((ptp = (LPTASKPACKET)lp) != NULL)
97             {
98             if ((ptp->idTask == taskUSER_ENUM) || (ptp->idTask == taskGROUP_ENUM))
99                Browse_OnEndTask_EnumObjects (hDlg, ptp);
100             else if (ptp->idTask == taskLIST_TRANSLATE)
101                Browse_OnEndTask_Translate (hDlg, ptp);
102             FreeTaskPacket (ptp);
103             }
104          break;
105
106       case WM_TIMER:
107          switch (wp)
108             {
109             case ID_SEARCH_TIMER:
110                if ( (l.dwTickLastType) && (GetTickCount() > l.dwTickLastType + msecSEARCH_TIMER) )
111                   {
112                   KillTimer (hDlg, ID_SEARCH_TIMER);
113                   Browse_UpdateDialog (hDlg);
114                   }
115                break;
116             }
117          break;
118
119       case WM_COMMAND:
120          switch (LOWORD(wp))
121             {
122             case IDC_BROWSE_SELECT:
123                Browse_OnOK (hDlg);
124                break;
125
126             case IDCANCEL:
127                EndDialog (hDlg, IDCANCEL);
128                break;
129
130             case IDC_BROWSE_CHECK:
131                Browse_UpdateDialog (hDlg);
132                break;
133
134             case IDC_BROWSE_COMBO:
135                if (HIWORD(wp) == CBN_SELCHANGE)
136                   {
137                   SetDlgItemText (hDlg, IDC_BROWSE_NAMED, TEXT(""));
138                   Browse_UpdateDialog (hDlg);
139                   }
140                break;
141
142             case IDC_BROWSE_RESTART:
143                Browse_UpdateDialog (hDlg);
144                PostMessage (hDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem (hDlg, IDC_BROWSE_NAMED), (LPARAM)TRUE);
145                break;
146
147             case IDC_BROWSE_NAMED:
148                if (HIWORD(wp) == EN_UPDATE)  // has the user hit Enter here?
149                   {
150                   TCHAR szTest[ 1024 ];
151                   GetDlgItemText (hDlg, IDC_BROWSE_NAMED, szTest, 1024);
152
153                   if ((lstrlen (szTest)) && (szTest[lstrlen(szTest)-1]==TEXT('\n')))
154                      {
155                      szTest[ lstrlen(szTest)-1 ] = TEXT('\0');
156                      if ((lstrlen (szTest)) && (szTest[lstrlen(szTest)-1]==TEXT('\r')))
157                         szTest[ lstrlen(szTest)-1 ] = TEXT('\0');
158
159                      SetDlgItemText (hDlg, IDC_BROWSE_NAMED, szTest);
160                      PostMessage (hDlg, WM_COMMAND, MAKELONG(IDC_BROWSE_SELECT,BN_CLICKED), (LPARAM)GetDlgItem(hDlg,IDC_BROWSE_SELECT));
161                      }
162                   }
163                break;
164
165             case IDC_BROWSE_PATTERN:
166                if (HIWORD(wp) == EN_UPDATE)
167                   {
168                   l.dwTickLastType = GetTickCount();
169                   KillTimer (hDlg, ID_SEARCH_TIMER);
170                   SetTimer (hDlg, ID_SEARCH_TIMER, msecSEARCH_TIMER +15, NULL);
171                   }
172                break;
173             }
174          break;
175
176       case WM_NOTIFY:
177          switch (((LPNMHDR)lp)->code)
178             {
179             case FLN_ITEMSELECT:
180                Browse_OnSelect (hDlg);
181                break;
182
183             case FLN_LDBLCLICK:
184                PostMessage (hDlg, WM_COMMAND, MAKELONG(IDC_BROWSE_SELECT,BN_CLICKED), (LPARAM)GetDlgItem (hDlg, IDC_BROWSE_SELECT));
185                break;
186             }
187          break;
188       }
189
190    return FALSE;
191 }
192
193
194 void Browse_OnInitDialog (HWND hDlg)
195 {
196    LPBROWSE_PARAMS lpp;
197    if ((lpp = (LPBROWSE_PARAMS)GetWindowLongPtr (hDlg, DWLP_USER)) != NULL)
198       {
199       // First, the text of the dialog is woefully ugly right now. Put
200       // in the strings which the caller supplied.
201       //
202       TCHAR szText[ cchRESOURCE ];
203       GetString (szText, lpp->idsTitle);
204       SetWindowText (hDlg, szText);
205
206       GetString (szText, lpp->idsPrompt);
207       SetDlgItemText (hDlg, IDC_BROWSE_TYPE, szText);
208
209       SetDlgItemText (hDlg, IDC_BROWSE_NAMED, lpp->szName);
210
211       SetDlgItemText (hDlg, IDC_BROWSE_PATTERN, TEXT(""));
212
213       ULONG status;
214       asc_CellNameGet_Fast (g.idClient, g.idCell, szText, &status);
215       SetDlgItemText (hDlg, IDC_BROWSE_CELL, szText);
216       EnableWindow (GetDlgItem (hDlg, IDC_BROWSE_CELL), FALSE);
217
218       if (GetDlgItem (hDlg, IDC_BROWSE_CHECK))
219          {
220          if (lpp->idsCheck == 0)
221             ShowWindow (GetDlgItem (hDlg, IDC_BROWSE_CHECK), FALSE);
222          else
223             {
224             GetString (szText, lpp->idsCheck);
225             SetDlgItemText (hDlg, IDC_BROWSE_CHECK, szText);
226             }
227
228          CheckDlgButton (hDlg, IDC_BROWSE_CHECK, (lpp->pObjectsToSkip) ? TRUE : FALSE);
229          }
230
231       if (GetDlgItem (hDlg, IDC_BROWSE_COMBO))
232          {
233          HWND hCombo = GetDlgItem (hDlg, IDC_BROWSE_COMBO);
234          LPARAM lpSelect = 0;
235          CB_StartChange (hCombo, TRUE);
236
237          if (lpp->TypeToShow & TYPE_USER)
238             {
239             CB_AddItem (hCombo, IDS_SHOW_USERS, TYPE_USER);
240             if (!lpSelect)
241                lpSelect = TYPE_USER;
242             }
243
244          if (lpp->TypeToShow & TYPE_GROUP)
245             {
246             CB_AddItem (hCombo, IDS_SHOW_GROUPS, TYPE_GROUP);
247             if (!lpSelect)
248                lpSelect = TYPE_GROUP;
249             }
250
251          CB_EndChange (hCombo, lpSelect);
252          }
253
254       // If the caller requested that we disallow multiple selection,
255       // change the fastlist's styles...
256       //
257       if (!lpp->fAllowMultiple)
258          {
259          DWORD dwStyle = GetWindowLong (GetDlgItem (hDlg, IDC_BROWSE_LIST), GWL_STYLE);
260          dwStyle &= ~(FLS_SELECTION_MULTIPLE);
261          SetWindowLong (GetDlgItem (hDlg, IDC_BROWSE_LIST), GWL_STYLE, dwStyle);
262          }
263
264       // Finally, update the listbox to show a valid list of users/groups.
265       // Oh--since we're in initdialog, add an imagelist to the window too.
266       //
267       FastList_SetImageLists (GetDlgItem (hDlg, IDC_BROWSE_LIST), AfsAppLib_CreateImageList(FALSE), NULL);
268       Browse_UpdateDialog (hDlg);
269       }
270 }
271
272
273 void Browse_OnSelect (HWND hDlg)
274 {
275    LPBROWSE_PARAMS lpp;
276    if ((lpp = (LPBROWSE_PARAMS)GetWindowLongPtr (hDlg, DWLP_USER)) != NULL)
277       {
278       if (!lpp->fQuerying)
279          {
280          HWND hList = GetDlgItem (hDlg, IDC_BROWSE_LIST);
281
282          static TCHAR szSeparator[ cchRESOURCE ] = TEXT("");
283          if (szSeparator[0] == TEXT('\0'))
284             {
285             if (!GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_SLIST, szSeparator, cchRESOURCE))
286                lstrcpy (szSeparator, TEXT(","));
287             lstrcat (szSeparator, TEXT(" "));
288             }
289
290          LPTSTR pszText = NULL;
291
292          HLISTITEM hItem = NULL;
293          while ((hItem = FastList_FindNextSelected (hList, hItem)) != NULL)
294             {
295             LPCTSTR pszName;
296             if ((pszName = FastList_GetItemText (hList, hItem, 0)) != NULL)
297                {
298                LPTSTR pszNew;
299                if (pszText)
300                   pszNew = FormatString (TEXT("%1%2%3"), TEXT("%s%s%s"), pszText, szSeparator, pszName);
301                else
302                   pszNew = FormatString (TEXT("%1"), TEXT("%s"), pszName);
303                if (pszText)
304                   FreeString (pszText);
305                pszText = pszNew;
306                }
307             if (pszText && !lpp->fAllowMultiple)
308                break;
309             }
310
311          SetDlgItemText (hDlg, IDC_BROWSE_NAMED, (pszText) ? pszText : TEXT(""));
312          if (pszText)
313             FreeString (pszText);
314          }
315       }
316 }
317
318
319 void Browse_OnOK (HWND hDlg)
320 {
321    LPBROWSE_PARAMS lpp;
322    if ((lpp = (LPBROWSE_PARAMS)GetWindowLongPtr (hDlg, DWLP_USER)) != NULL)
323       {
324       LPTSTR pszNames = GetEditText (GetDlgItem (hDlg, IDC_BROWSE_NAMED));
325
326       // Disable the controls on the dialog for a bit...
327       //
328       Browse_Enable (hDlg, FALSE);
329
330       // Start a background task to translate the typed list-of-names into
331       // a usable ASID list. When it comes back, we'll close the dialog.
332       //
333       LPLIST_TRANSLATE_PARAMS pTask = New (LIST_TRANSLATE_PARAMS);
334       pTask->Type = Browse_GetSelectedType (hDlg);
335       pTask->pszNames = pszNames;
336       StartTask (taskLIST_TRANSLATE, hDlg, pTask);
337       }
338 }
339
340
341 void Browse_OnEndTask_EnumObjects (HWND hDlg, LPTASKPACKET ptp)
342 {
343    LPBROWSE_PARAMS lpp;
344    size_t ii;
345    if ((lpp = (LPBROWSE_PARAMS)GetWindowLongPtr (hDlg, DWLP_USER)) != NULL)
346       {
347       HWND hList = GetDlgItem (hDlg, IDC_BROWSE_LIST);
348       FastList_Begin (hList);
349       FastList_RemoveAll (hList);
350
351       // If we were successful, we now have a list of all objects of the
352       // appropriate type. However, the user may not want us to display
353       // items which are on our pObjectsToSkip list; if not, convert the
354       // later to a hashlist (for fast lookup) and remove the offending
355       // entries from the former.
356       //
357       if (ptp->rc && TASKDATA(ptp)->pAsidList)
358          {
359          if ((IsDlgButtonChecked (hDlg, IDC_BROWSE_CHECK)) && (lpp->pObjectsToSkip))
360             {
361             LPHASHLIST pListToSkip = New (HASHLIST);
362
363             for (ii = 0; ii < lpp->pObjectsToSkip->cEntries; ++ii)
364                pListToSkip->AddUnique ((PVOID)(lpp->pObjectsToSkip->aEntries[ii].idObject));
365
366             for (ii = 0; ii < TASKDATA(ptp)->pAsidList->cEntries; )
367                {
368                if (pListToSkip->fIsInList ((PVOID)(TASKDATA(ptp)->pAsidList->aEntries[ii].idObject)))
369                   asc_AsidListRemoveEntryByIndex (&TASKDATA(ptp)->pAsidList, ii);
370                else
371                   ii++;
372                }
373
374             Delete (pListToSkip);
375             }
376          }
377
378       // OK, we're ready to go--populate that list!
379       //
380       for (ii = 0; ii < TASKDATA(ptp)->pAsidList->cEntries; ++ii)
381          {
382          ULONG status;
383          ASOBJPROP Properties;
384          if (!asc_ObjectPropertiesGet_Fast (g.idClient, g.idCell, TASKDATA(ptp)->pAsidList->aEntries[ii].idObject, &Properties, &status))
385             continue;
386
387          TCHAR szName[ MAX_PATH ];
388          if (Properties.Type == TYPE_USER)
389             User_GetDisplayName (szName, &Properties);
390          else
391             lstrcpy (szName, Properties.szName);
392
393          FASTLISTADDITEM flai;
394          memset (&flai, 0x00, sizeof(flai));
395          flai.iFirstImage = (Properties.Type == TYPE_USER) ? imageUSER : (Properties.Type == TYPE_GROUP) ? imageGROUP : IMAGE_NOIMAGE;
396          flai.iSecondImage = IMAGE_NOIMAGE;
397          flai.pszText = szName;
398          FastList_AddItem (hList, &flai);
399          }
400
401       FastList_End (hList);
402       lpp->fQuerying --;
403       }
404 }
405
406
407 void Browse_OnEndTask_Translate (HWND hDlg, LPTASKPACKET ptp)
408 {
409    LPBROWSE_PARAMS lpp;
410     if ((lpp = (LPBROWSE_PARAMS)GetWindowLongPtr (hDlg, DWLP_USER)) != NULL)
411       {
412       if (!ptp->rc || !TASKDATA(ptp)->pAsidList || !TASKDATA(ptp)->pAsidList->cEntries)
413          {
414          ErrorDialog (ptp->status, (TASKDATA(ptp)->Type == TYPE_USER) ? IDS_ERROR_CANT_TRANSLATE_USER : IDS_ERROR_CANT_TRANSLATE_GROUP);
415          Browse_Enable (hDlg, TRUE);
416          }
417       else
418          {
419          lpp->pObjectsSelected = TASKDATA(ptp)->pAsidList;
420          TASKDATA(ptp)->pAsidList = NULL; // don't let FreeTaskPacket free this
421
422          // Fill in {lpp->szName}, for convenience
423          //
424          lpp->szName[0] = TEXT('\0');
425
426          if (lpp->pObjectsSelected && lpp->pObjectsSelected->cEntries)
427             {
428             ULONG status;
429             ASOBJPROP Properties;
430             if (asc_ObjectPropertiesGet_Fast (g.idClient, g.idCell, lpp->pObjectsSelected->aEntries[0].idObject, &Properties, &status))
431                lstrcpy (lpp->szName, Properties.szName);
432             }
433
434          EndDialog (hDlg, IDOK);
435          }
436       }
437 }
438
439
440 void Browse_UpdateDialog (HWND hDlg)
441 {
442    LPBROWSE_PARAMS lpp;
443    if ((lpp = (LPBROWSE_PARAMS)GetWindowLongPtr (hDlg, DWLP_USER)) != NULL)
444       {
445       lpp->fQuerying ++;
446
447       // First we'll need to empty the list, and add some non-selectable thing
448       // that says "querying"
449       //
450       HWND hList = GetDlgItem (hDlg, IDC_BROWSE_LIST);
451       FastList_Begin (hList);
452       FastList_RemoveAll (hList);
453
454       TCHAR szText[ cchRESOURCE ];
455       GetString (szText, IDS_QUERYING_LONG);
456
457       FASTLISTADDITEM flai;
458       memset (&flai, 0x00, sizeof(flai));
459       flai.iFirstImage = IMAGE_NOIMAGE;
460       flai.iSecondImage = IMAGE_NOIMAGE;
461       flai.pszText = szText;
462       flai.dwFlags = FLIF_DISALLOW_SELECT;
463       FastList_AddItem (hList, &flai);
464
465       FastList_End (hList);
466
467       // Then start a background task to obtain the appropriate list
468       // of stuff to show. When that task completes, we'll populate the
469       // list.
470       //
471       TCHAR szPattern[ cchNAME ];
472       GetDlgItemText (hDlg, IDC_BROWSE_PATTERN, szPattern, cchNAME);
473
474       LPTSTR pszPattern = NULL;
475       if (szPattern[0] != TEXT('\0'))
476          pszPattern = CloneString (szPattern);
477
478       StartTask ((Browse_GetSelectedType (hDlg) == TYPE_USER) ? taskUSER_ENUM : taskGROUP_ENUM, hDlg, pszPattern);
479       }
480 }
481
482
483 void Browse_Enable (HWND hDlg, BOOL fEnable)
484 {
485    EnableWindow (GetDlgItem (hDlg, IDC_BROWSE_LIST), fEnable);
486    EnableWindow (GetDlgItem (hDlg, IDC_BROWSE_SELECT), fEnable);
487    EnableWindow (GetDlgItem (hDlg, IDC_BROWSE_NAMED), fEnable);
488    EnableWindow (GetDlgItem (hDlg, IDC_BROWSE_CHECK), fEnable);
489    EnableWindow (GetDlgItem (hDlg, IDCANCEL), fEnable);
490 }
491
492
493 ASOBJTYPE Browse_GetSelectedType (HWND hDlg)
494 {
495    HWND hCombo;
496    if ((hCombo = GetDlgItem (hDlg, IDC_BROWSE_COMBO)) != NULL)
497       {
498       return (ASOBJTYPE)CB_GetSelectedData (hCombo);
499       }
500
501    LPBROWSE_PARAMS lpp;
502    if ((lpp = (LPBROWSE_PARAMS)GetWindowLongPtr (hDlg, DWLP_USER)) != NULL)
503       {
504       return lpp->TypeToShow;
505       }
506
507    return (ASOBJTYPE)0;
508 }
509