Windows: remove trailing whitespace
[openafs.git] / src / WINNT / afsusrmgr / action.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 "action.h"
17 #include "window.h"
18
19
20 /*
21  * DEFINITIONS ________________________________________________________________
22  *
23  */
24
25 #define ID_ACTION_TIMER  100
26
27 typedef enum
28    {
29    actcolOPERATION,
30    actcolELAPSED,
31    } ACTIONCOLUMN;
32
33 static struct
34    {
35    int idsColumn;
36    int cxWidth;
37    }
38 ACTIONCOLUMNS[] =
39    {
40       { IDS_ACTCOL_OPERATION, 100 }, // actcolOPERATIONS
41       { IDS_ACTCOL_ELAPSED,   100 }, // actcolELAPSED
42    };
43
44 #define nACTIONCOLUMNS  (sizeof(ACTIONCOLUMNS)/sizeof(ACTIONCOLUMNS[0]))
45
46 #define cxMIN_ACTION  75
47 #define cyMIN_ACTION  50
48
49
50 /*
51  * VARIABLES __________________________________________________________________
52  *
53  */
54
55 static struct
56    {
57    HWND hAction;
58    LPASACTIONLIST pActionList;
59    } l;
60
61 rwWindowData awdActions[] = {
62     { IDC_ACTION_DESC, raSizeX | raRepaint,                                     0,      0 },
63     { IDC_ACTION_LIST, raSizeX | raSizeY, MAKELONG(cxMIN_ACTION,cyMIN_ACTION),  0 },
64     { idENDLIST, 0,                                                             0,      0 }
65  };
66
67
68 /*
69  * PROTOTYPES _________________________________________________________________
70  *
71  */
72
73 void TicksToElapsedTime (LPSYSTEMTIME pst, DWORD dwTicks);
74 LPTSTR GetActionDescription (LPASACTION pAction);
75
76 BOOL CALLBACK Actions_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp);
77 void Actions_OnEndTask_GetActions (LPTASKPACKET ptp);
78 void Actions_Refresh (void);
79
80
81 /*
82  * ROUTINES ___________________________________________________________________
83  *
84  */
85
86 void TicksToElapsedTime (LPSYSTEMTIME pst, DWORD dwTicks)
87 {
88 #define msecSECOND  (1000L)
89 #define msecMINUTE  (1000L * 60L)
90 #define msecHOUR    (1000L * 60L * 60L)
91 #define msecDAY     (1000L * 60L * 60L * 24L)
92
93    memset (pst, 0x00, sizeof(SYSTEMTIME));
94
95    pst->wDay = (int)( dwTicks / msecDAY );
96    dwTicks %= msecDAY;
97    pst->wHour = (int)( dwTicks / msecHOUR );
98    dwTicks %= msecHOUR;
99    pst->wMinute = (int)( dwTicks / msecMINUTE );
100    dwTicks %= msecMINUTE;
101    pst->wSecond = (int)( dwTicks / msecSECOND );
102    dwTicks %= msecSECOND;
103    pst->wMilliseconds = (int)( dwTicks );
104 }
105
106
107 void FixActionTime (DWORD *pcsec)
108 {
109    DWORD dwTickNow = GetTickCount();
110    DWORD cTickActive = 1000L * (*pcsec);
111    (*pcsec) = dwTickNow - cTickActive;
112 }
113
114
115 void Actions_SetDefaultView (LPVIEWINFO lpvi)
116 {
117    lpvi->lvsView = FLS_VIEW_LIST;
118    lpvi->nColsAvail = nACTIONCOLUMNS;
119
120    for (size_t iCol = 0; iCol < nACTIONCOLUMNS; ++iCol)
121       {
122       lpvi->cxColumns[ iCol ]  = ACTIONCOLUMNS[ iCol ].cxWidth;
123       lpvi->idsColumns[ iCol ] = ACTIONCOLUMNS[ iCol ].idsColumn;
124       }
125
126    lpvi->iSort = actcolELAPSED | COLUMN_SORTREV;
127
128    lpvi->nColsShown = 2;
129    lpvi->aColumns[0] = (int)actcolOPERATION;
130    lpvi->aColumns[1] = (int)actcolELAPSED;
131 }
132
133
134 void Actions_OpenWindow (void)
135 {
136    if (!IsWindow (l.hAction))
137       {
138       l.hAction = ModelessDialog (IDD_ACTIONS, NULL, (DLGPROC)Actions_DlgProc);
139       ShowWindow (l.hAction, SW_SHOW);
140       Actions_WindowToTop (TRUE);
141       }
142 }
143
144
145 void Actions_CloseWindow (void)
146 {
147    if (IsWindow (l.hAction))
148       {
149       DestroyWindow (l.hAction);
150       l.hAction = NULL;
151       }
152 }
153
154
155 void Actions_WindowToTop (BOOL fTop)
156 {
157    if (IsWindow(l.hAction))
158       {
159       if (fTop)
160          {
161          SetWindowPos (l.hAction, HWND_TOPMOST, 0, 0, 0, 0,
162                        SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
163          }
164       else //(!fTop)
165          {
166          SetWindowPos (l.hAction, g.hMain, 0, 0, 0, 0,
167                        SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
168          }
169       }
170 }
171
172
173 BOOL CALLBACK Actions_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
174 {
175    if (Display_HandleColumnNotify (hDlg, msg, wp, lp, &gr.viewAct))
176       return FALSE;
177
178    if (msg == WM_INITDIALOG)
179       l.hAction = hDlg;
180
181    switch (msg)
182       {
183       case WM_INITDIALOG:
184          {
185          HWND hList = GetDlgItem (hDlg, IDC_ACTION_LIST);
186          FL_RestoreView (hList, &gr.viewAct);
187
188          if (gr.rActions.right == 0)
189             GetWindowRect (hDlg, &gr.rActions);
190          ResizeWindow (hDlg, awdActions, rwaMoveToHere, &gr.rActions);
191
192          SetTimer (hDlg, ID_ACTION_TIMER, 1000, NULL);  // timer message every sec
193
194          StartTask (taskGET_ACTIONS, l.hAction);
195          gr.fShowActions = TRUE;
196          break;
197          }
198
199       case WM_DESTROY:
200          gr.fShowActions = FALSE;
201          l.hAction = NULL;
202          Main_SetMenus();
203          KillTimer (hDlg, ID_ACTION_TIMER);
204
205          if (l.pActionList)
206             asc_ActionListFree (&l.pActionList);
207          break;
208
209       case WM_TIMER:
210          if ((FastList_GetItemCount (GetDlgItem (hDlg, IDC_ACTION_LIST))) || (l.pActionList && l.pActionList->cEntries))
211             Actions_Refresh();
212          break;
213
214       case WM_SIZE:
215          // if (lp==0), we're minimizing--don't call ResizeWindow().
216          //
217          if (lp != 0)
218             {
219             ResizeWindow (hDlg, awdActions, rwaFixupGuts);
220             GetWindowRect (hDlg, &gr.rActions);
221             }
222          break;
223
224       case WM_MOVE:
225          GetWindowRect (hDlg, &gr.rActions);
226          break;
227
228       case WM_ENDTASK:
229          LPTASKPACKET ptp;
230          if ((ptp = (LPTASKPACKET)lp) != NULL)
231             {
232             if (ptp->idTask == taskGET_ACTIONS)
233                Actions_OnEndTask_GetActions (ptp);
234             FreeTaskPacket (ptp);
235             }
236          break;
237
238       case WM_COMMAND:
239          switch (LOWORD(wp))
240             {
241             case IDOK:
242             case IDCANCEL:
243                DestroyWindow (hDlg);
244                break;
245             }
246          break;
247       }
248
249    return FALSE;
250 }
251
252
253 void Actions_OnNotify (WPARAM wp, LPARAM lp)
254 {
255    LPASACTION pAction = (LPASACTION)lp;
256    BOOL fFinished = (BOOL)wp;
257
258    if (pAction)
259       {
260       // We've just been told something happened;
261       //
262       switch (pAction->Action)
263          {
264          case ACTION_REFRESH:
265             // If we get a Finished Refreshing notification, it's a safe bet
266             // that the admin server has done a significant refresh to its
267             // cache; so, we'll use that as a trigger to repopulate the lists
268             // on the main dialog.
269             //
270             if (fFinished)
271                Display_PopulateList();
272             break;
273          }
274
275       // If the Actions window is being displayed, use this notification
276       // to update our stored list-of-actions.
277       //
278       if (IsWindow (l.hAction))
279          {
280          if (!fFinished)
281             FixActionTime (&pAction->csecActive);
282
283          if (!l.pActionList)
284             asc_ActionListCreate (&l.pActionList);
285
286          if (l.pActionList)
287             {
288             if (fFinished)
289                asc_ActionListRemoveEntry (&l.pActionList, pAction->idAction);
290             else if (!asc_ActionListTest (&l.pActionList, pAction->idAction))
291                asc_ActionListAddEntry (&l.pActionList, pAction);
292             }
293
294          Actions_Refresh();
295          }
296
297       Delete (pAction);
298       }
299 }
300
301
302 void Actions_OnEndTask_GetActions (LPTASKPACKET ptp)
303 {
304    if (l.pActionList)
305       {
306       asc_ActionListFree (&l.pActionList);
307       }
308    if (ptp->rc && TASKDATA(ptp)->pActionList)
309       {
310       l.pActionList = TASKDATA(ptp)->pActionList;
311       TASKDATA(ptp)->pActionList = NULL; // don't let FreeTaskPacket free this
312
313       // Zip through the listed actions and change the reported csec-elapsed
314       // into an estimated starting tick.
315       //
316       for (size_t ii = 0; ii < l.pActionList->cEntries; ++ii)
317          {
318          FixActionTime (&l.pActionList->aEntries[ ii ].Action.csecActive);
319          }
320       }
321    Actions_Refresh();
322 }
323
324
325 void Actions_Refresh (void)
326 {
327    size_t nItems = 0;
328    TCHAR szText[ cchRESOURCE ];
329
330    HWND hList;
331    if ((hList = GetDlgItem (l.hAction, IDC_ACTION_LIST)) != NULL)
332       {
333       LPARAM lpOld = FL_StartChange (hList, TRUE);
334
335       if (l.pActionList)
336          {
337          for (size_t ii = 0; ii < l.pActionList->cEntries; ++ii)
338             {
339             LPTSTR pszDesc;
340             if ((pszDesc = GetActionDescription (&l.pActionList->aEntries[ ii ].Action)) != NULL)
341                {
342                SYSTEMTIME st;
343                TicksToElapsedTime (&st, GetTickCount() - l.pActionList->aEntries[ ii ].Action.csecActive);
344                FormatElapsed (szText, TEXT("%s"), &st);
345
346                FASTLISTADDITEM flai;
347                memset (&flai, 0x00, sizeof(flai));
348                flai.hParent = NULL;
349                flai.iFirstImage = IMAGE_NOIMAGE;
350                flai.iSecondImage = IMAGE_NOIMAGE;
351                flai.pszText = pszDesc;
352                flai.lParam = (LPARAM)ii;
353                flai.dwFlags = FLIF_DISALLOW_SELECT;
354
355                HLISTITEM hItem;
356                if ((hItem = FastList_AddItem (hList, &flai)) != NULL)
357                   FastList_SetItemText (hList, hItem, 1, szText);
358
359                ++nItems;
360
361                FreeString (pszDesc);
362                }
363             }
364          }
365
366       FL_EndChange (hList, lpOld);
367       }
368
369    if (nItems == 0)
370       GetString (szText, IDS_ACTION_DESC_NONE);
371    else if (nItems == 1)
372       GetString (szText, IDS_ACTION_DESC_ONE);
373    else // (nItems >= 2)
374       GetString (szText, IDS_ACTION_DESC_MULT);
375    SetDlgItemText (l.hAction, IDC_ACTION_DESC, szText);
376 }
377
378
379 LPTSTR GetActionDescription (LPASACTION pAction)
380 {
381    LPTSTR pszDesc = NULL;
382
383    ULONG status;
384    ASOBJPROP Properties;
385    ASOBJPROP Properties2;
386
387    switch (pAction->Action)
388       {
389       case ACTION_REFRESH:
390          if (asc_ObjectPropertiesGet_Fast (g.idClient, g.idCell, pAction->u.Refresh.idScope, &Properties, &status))
391             {
392             if (Properties.Type == TYPE_CELL)
393                pszDesc = FormatString (IDS_ACTION_REFRESH_CELL, TEXT("%s"), Properties.szName);
394             else if (Properties.Type == TYPE_SERVER)
395                pszDesc = FormatString (IDS_ACTION_REFRESH_SERVER, TEXT("%s"), Properties.szName);
396             }
397          break;
398
399       case ACTION_SCOUT:
400          if (asc_ObjectPropertiesGet_Fast (g.idClient, g.idCell, pAction->u.Refresh.idScope, &Properties, &status))
401             {
402             if (Properties.Type == TYPE_CELL)
403                pszDesc = FormatString (IDS_ACTION_SCOUT_CELL, TEXT("%s"), Properties.szName);
404             else if (Properties.Type == TYPE_SERVER)
405                pszDesc = FormatString (IDS_ACTION_SCOUT_SERVER, TEXT("%s"), Properties.szName);
406             }
407          break;
408
409       case ACTION_USER_CHANGE:
410          if (asc_ObjectPropertiesGet_Fast (g.idClient, g.idCell, pAction->u.User_Change.idUser, &Properties, &status))
411             {
412             pszDesc = FormatString (IDS_ACTION_USER_CHANGE, TEXT("%s"), Properties.szName);
413             }
414          break;
415
416       case ACTION_USER_PW_CHANGE:
417          if (asc_ObjectPropertiesGet_Fast (g.idClient, g.idCell, pAction->u.User_Pw_Change.idUser, &Properties, &status))
418             {
419             pszDesc = FormatString (IDS_ACTION_USER_PW_CHANGE, TEXT("%s"), Properties.szName);
420             }
421          break;
422
423       case ACTION_USER_UNLOCK:
424          if (asc_ObjectPropertiesGet_Fast (g.idClient, g.idCell, pAction->u.User_Unlock.idUser, &Properties, &status))
425             {
426             pszDesc = FormatString (IDS_ACTION_USER_UNLOCK, TEXT("%s"), Properties.szName);
427             }
428          break;
429
430       case ACTION_USER_CREATE:
431          pszDesc = FormatString (IDS_ACTION_USER_CREATE, TEXT("%s"), pAction->u.User_Create.szUser);
432          break;
433
434       case ACTION_USER_DELETE:
435          if (asc_ObjectPropertiesGet_Fast (g.idClient, g.idCell, pAction->u.User_Delete.idUser, &Properties, &status))
436             {
437             pszDesc = FormatString (IDS_ACTION_USER_DELETE, TEXT("%s"), Properties.szName);
438             }
439          break;
440
441       case ACTION_GROUP_CHANGE:
442          if (asc_ObjectPropertiesGet_Fast (g.idClient, g.idCell, pAction->u.Group_Change.idGroup, &Properties, &status))
443             {
444             pszDesc = FormatString (IDS_ACTION_GROUP_CHANGE, TEXT("%s"), Properties.szName);
445             }
446          break;
447
448       case ACTION_GROUP_MEMBER_ADD:
449          if (asc_ObjectPropertiesGet_Fast (g.idClient, g.idCell, pAction->u.Group_Member_Add.idGroup, &Properties, &status))
450             {
451             if (asc_ObjectPropertiesGet_Fast (g.idClient, g.idCell, pAction->u.Group_Member_Add.idUser, &Properties2, &status))
452                {
453                pszDesc = FormatString (IDS_ACTION_GROUP_MEMBER_ADD, TEXT("%s%s"), Properties.szName, Properties2.szName);
454                }
455             }
456          break;
457
458       case ACTION_GROUP_MEMBER_REMOVE:
459          if (asc_ObjectPropertiesGet_Fast (g.idClient, g.idCell, pAction->u.Group_Member_Remove.idGroup, &Properties, &status))
460             {
461             if (asc_ObjectPropertiesGet_Fast (g.idClient, g.idCell, pAction->u.Group_Member_Remove.idUser, &Properties2, &status))
462                {
463                pszDesc = FormatString (IDS_ACTION_GROUP_MEMBER_REMOVE, TEXT("%s%s"), Properties.szName, Properties2.szName);
464                }
465             }
466          break;
467
468       case ACTION_GROUP_RENAME:
469          if (asc_ObjectPropertiesGet_Fast (g.idClient, g.idCell, pAction->u.Group_Rename.idGroup, &Properties, &status))
470             {
471             pszDesc = FormatString (IDS_ACTION_GROUP_RENAME, TEXT("%s%s"), Properties.szName, pAction->u.Group_Rename.szNewName);
472             }
473          break;
474
475       case ACTION_GROUP_CREATE:
476          pszDesc = FormatString (IDS_ACTION_GROUP_CREATE, TEXT("%s"), pAction->u.Group_Create.szGroup);
477          break;
478
479       case ACTION_GROUP_DELETE:
480          if (asc_ObjectPropertiesGet_Fast (g.idClient, g.idCell, pAction->u.Group_Delete.idGroup, &Properties, &status))
481             {
482             pszDesc = FormatString (IDS_ACTION_GROUP_DELETE, TEXT("%s"), Properties.szName);
483             }
484          break;
485
486       case ACTION_CELL_CHANGE:
487          if (asc_ObjectPropertiesGet_Fast (g.idClient, g.idCell, g.idCell, &Properties, &status))
488             {
489             pszDesc = FormatString (IDS_ACTION_CELL_CHANGE, TEXT("%s"), Properties.szName);
490             }
491          break;
492       }
493
494    return pszDesc;
495 }
496