windows-aklog-cleanup-20080321
[openafs.git] / src / WINNT / afssvrmgr / svr_window.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 #include <winsock2.h>
11 #include <ws2tcpip.h>
12
13 extern "C" {
14 #include <afs/param.h>
15 #include <afs/stds.h>
16 }
17
18 #include "svrmgr.h"
19 #include "svr_window.h"
20 #include "propcache.h"
21 #include "set_tab.h"
22 #include "agg_tab.h"
23 #include "svc_tab.h"
24 #include "display.h"
25 #include "command.h"
26
27
28 /*
29  * RESIZING WINDOWS ___________________________________________________________
30  *
31  */
32
33 #define cxMIN_SERVER 100
34 #define cyMIN_SERVER 100
35
36 static rwWindowData awdServer[] = {
37     { IDC_TABS,  raSizeX | raSizeY,     MAKELONG(cxMIN_SERVER,cyMIN_SERVER),    0 },
38     { idENDLIST, 0,                     0,                                      0 }
39  };
40
41 static rwWindowData awdTabChild[] = {
42     { 0,         raSizeX | raSizeY,     0,      0 },
43     { idENDLIST, 0,                     0,      0  }
44  };
45
46
47 /*
48  * CHILD TABS _________________________________________________________________
49  *
50  */
51
52 static struct // CHILDTABINFO
53    {
54    CHILDTAB tab;
55    int idsTabTitle;
56    int iImage;
57    }
58 CHILDTABINFO[] =
59    {
60       { tabFILESETS,   IDS_TAB_FILESETS,   imageFILESET   },
61       { tabAGGREGATES, IDS_TAB_AGGREGATES, imageAGGREGATE },
62       { tabSERVICES,   IDS_TAB_SERVICES,   imageSERVICE   },
63    };
64
65 #define nCHILDTABS (sizeof(CHILDTABINFO)/sizeof(CHILDTABINFO[0]))
66
67
68
69 /*
70  * PROTOTYPES _________________________________________________________________
71  *
72  */
73
74 BOOL CALLBACK Server_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp);
75
76 void Server_SaveRect (HWND hDlg, BOOL fOpen);
77
78 BOOL Server_HandleDialogKeys (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp);
79
80
81 /*
82  * ROUTINES ___________________________________________________________________
83  *
84  */
85
86 void Server_Open (LPIDENT lpiServer, LPRECT prWindow)
87 {
88    HWND hServer;
89
90    if ((hServer = PropCache_Search (pcSERVER, lpiServer)) != NULL)
91       {
92       SetFocus (hServer);
93       }
94    else
95       {
96       // First off, if this server isn't being monitored, we have
97       // to start monitoring it or we can't open a window (nothing to
98       // show otherwise).
99       //
100       LPSERVER_PREF lpsp;
101       if ((lpsp = (LPSERVER_PREF)lpiServer->GetUserParam()) != NULL)
102          {
103          BOOL fCanShowWindow = (gr.fOpenMonitors || lpsp->fIsMonitored);
104
105          if (gr.fOpenMonitors && !lpsp->fIsMonitored)
106             {
107             StartTask (taskSVR_MONITOR_ONOFF, NULL, lpiServer);
108             }
109
110          if (fCanShowWindow)
111             {
112             hServer = ModelessDialogParam (IDD_SERVER, NULL, (DLGPROC)Server_DlgProc, (LPARAM)lpiServer);
113             Server_SelectServer (hServer, lpiServer);
114
115             if (prWindow->right != 0)
116                {
117                SetWindowPos (hServer, NULL, prWindow->left, prWindow->top,
118                              cxRECT(*prWindow), cyRECT(*prWindow),
119                              SWP_NOZORDER | SWP_NOACTIVATE);
120                }
121
122             ShowWindow (hServer, SW_NORMAL);
123             }
124          }
125       }
126 }
127
128
129 void Server_Close (LPIDENT lpiServer)
130 {
131    HWND hWnd;
132
133    if ((hWnd = PropCache_Search (pcSERVER, lpiServer)) != NULL)
134       {
135       Server_SaveRect (hWnd, FALSE);
136       DestroyWindow (hWnd);
137
138       // If there's a subset active, the user may want us to stop
139       // monitoring this server once its window is closed.
140       //
141       LPSERVER_PREF lpsp;
142       if ((lpsp = (LPSERVER_PREF)lpiServer->GetUserParam()) != NULL)
143          {
144          if (g.sub && gr.fCloseUnmonitors && lpsp->fIsMonitored && !gr.fPreview)
145             {
146             StartTask (taskSVR_MONITOR_ONOFF, NULL, lpiServer);
147             }
148          }
149       }
150 }
151
152
153 void Server_CloseAll (BOOL fUserRequested)
154 {
155    HWND hWnd;
156
157    while ((hWnd = PropCache_Search (pcSERVER, ANYVALUE)) != NULL)
158       {
159       LPIDENT lpiServer = Server_GetServer (hWnd);
160
161       Server_SaveRect (hWnd, !fUserRequested);
162       DestroyWindow (hWnd);
163
164       if (lpiServer && fUserRequested)
165          {
166          // If there's a subset active, the user may want us to stop
167          // monitoring this server once its window is closed.
168          //
169          LPSERVER_PREF lpsp;
170          if ((lpsp = (LPSERVER_PREF)lpiServer->GetUserParam()) != NULL)
171             {
172             if (g.sub && gr.fCloseUnmonitors && lpsp->fIsMonitored)
173                {
174                StartTask (taskSVR_MONITOR_ONOFF, NULL, lpiServer);
175                }
176             }
177          }
178       }
179 }
180
181
182 HWND Server_GetCurrentTab (HWND hWnd)
183 {
184    return GetTabChild (GetDlgItem (hWnd, IDC_TABS));
185 }
186
187 CHILDTAB Server_GetDisplayedTab (HWND hWnd)
188 {
189    HWND hTabs = GetDlgItem (hWnd, IDC_TABS);
190    return (hTabs) ? (CHILDTAB)TabCtrl_GetCurSel(hTabs) : tabINVALID;
191 }
192
193 HWND Server_GetWindowForChild (HWND hChild)
194 {
195    // hChild is the Filesets_DlgProc dialog (or whatever)
196    // Its parent is the tab control on the server window
197    // Its grandparent is the Popup HWND (may be g.hMain) that we want.
198    //
199    return GetParent (GetParent (hChild));
200 }
201
202 void Server_SelectServer (HWND hDlg, LPIDENT lpiNew, BOOL fForceRedraw)
203 {
204    LPIDENT lpiOld = Server_GetServer (hDlg);
205    if (lpiNew != lpiOld)
206       {
207       SetWindowLongPtr (hDlg, DWLP_USER, (LONG_PTR)lpiNew);
208
209       if (hDlg != g.hMain)
210          {
211          if (lpiOld)
212             PropCache_Delete (pcSERVER, lpiOld);
213
214          if (lpiNew)
215             {
216             PropCache_Add (pcSERVER, lpiNew, hDlg);
217
218             TCHAR szName[ cchNAME ];
219             lpiNew->GetServerName (szName);
220             LPTSTR pszTitle = FormatString (IDS_SERVER_TITLE, TEXT("%s"), szName);
221             SetWindowText (hDlg, pszTitle);
222             FreeString (pszTitle);
223             }
224          }
225
226       fForceRedraw = TRUE;
227       }
228
229    if (fForceRedraw)
230       {
231       Server_ForceRedraw (hDlg);
232       }
233 }
234
235 LPIDENT Server_GetServer (HWND hDlg)
236 {
237    return (LPIDENT)GetWindowLongPtr (hDlg, DWLP_USER);
238 }
239
240 LPIDENT Server_GetServerForChild (HWND hChild)
241 {
242    if (GetParent(hChild) == NULL)
243       return Server_GetServer (hChild);
244    else
245       return Server_GetServer (GetParent(GetParent(hChild)));
246 }
247
248
249 void Server_ForceRedraw (HWND hDlg)
250 {
251    HWND hChild = Server_GetCurrentTab (hDlg);
252
253    if (hChild && IsWindow (hChild))
254       {
255       PostMessage (hChild, WM_SERVER_CHANGED, 0, 0);
256       }
257 }
258
259
260 /*
261  * SERVER DIALOG ______________________________________________________________
262  *
263  */
264
265 BOOL CALLBACK Server_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
266 {
267    LPIDENT lpiServer = Server_GetServer (hDlg);
268
269    if (Server_HandleDialogKeys (hDlg, msg, wp, lp))
270       return TRUE;
271
272    switch (msg)
273       {
274       case WM_INITDIALOG:
275          RECT rWindow;
276          Server_PrepareTabControl (GetDlgItem (hDlg, IDC_TABS));
277          GetWindowRect (hDlg, &rWindow);
278          ResizeWindow (hDlg, awdServer, rwaMoveToHere, &rWindow);
279          break;
280
281       case WM_HELP:
282          WinHelp (hDlg, cszHELPFILENAME, HELP_FINDER, 0);
283          break;
284
285       case WM_DESTROY:
286          GetWindowRect (hDlg, &gr.rServerLast);
287
288          if (lpiServer)
289             PropCache_Delete (pcSERVER, lpiServer);
290          break;
291
292       case WM_SIZE:
293          // if (lp==0), we're minimizing--don't call ResizeWindow().
294          //
295          if (lp != 0)
296             {
297             ResizeWindow (hDlg, awdServer, rwaFixupGuts);
298             Server_SaveRect (hDlg, TRUE);
299             }
300          break;
301
302       case WM_MOVE:
303          Server_SaveRect (hDlg, TRUE);
304          break;
305
306       case WM_SETFOCUS:
307          gr.tabLast = Server_GetDisplayedTab (hDlg);
308          break;
309
310       case WM_COMMAND:
311          switch (LOWORD(wp))
312             {
313             case IDCANCEL:
314                LPIDENT lpi;
315                if ((lpi = Server_GetServer (hDlg)) != NULL)
316                   Server_Close (lpi);
317                else
318                   DestroyWindow (hDlg);
319                break;
320             }
321          break;
322
323       case WM_NOTIFY: 
324          switch (((LPNMHDR)lp)->code)
325             { 
326             case TCN_SELCHANGE:
327                { 
328                HWND hTab = GetDlgItem (hDlg, IDC_TABS);
329                int iPage = TabCtrl_GetCurSel (hTab); 
330
331                Server_DisplayTab (hDlg, (CHILDTAB)iPage);
332                gr.tabLast = (CHILDTAB)iPage;
333                }
334                break;
335             }
336          break;
337       }
338
339    return FALSE;
340 }
341
342
343 static LONG_PTR procTabControl = 0;
344
345 LRESULT CALLBACK Server_SubclassTabControlProc (HWND hTab, UINT msg, WPARAM wp, LPARAM lp)
346 {
347    LRESULT rc;
348
349    if (procTabControl == 0)
350       rc = DefWindowProc (hTab, msg, wp, lp);
351    else
352       rc = (LRESULT) CallWindowProc ((WNDPROC)procTabControl, hTab, msg, wp, lp);
353
354    switch (msg)
355       {
356       // Since this is a subclass proc, it's not around when the window
357       // is created.  Any WM_CREATE processing we'd ordinarily do here
358       // must therefore be done at the point where the tab control is
359       // subclassed.
360       //
361       // case WM_CREATE:
362
363       case WM_SIZE:
364          if (lp != 0)
365             ResizeWindow (hTab, awdTabChild, rwaFixupGuts);
366          break;
367
368       case WM_DESTROY:
369          if (procTabControl != 0)
370             SetWindowLongPtr (hTab, GWLP_WNDPROC, procTabControl);
371          break;
372       }
373
374    return rc;
375 }
376
377
378 void Server_PrepareTabControl (HWND hTab)
379 {
380    TabCtrl_SetImageList (hTab, AfsAppLib_CreateImageList (FALSE));
381
382    TCHAR szText[ cchRESOURCE ];
383    TC_ITEM tci;
384    tci.mask = TCIF_TEXT | TCIF_PARAM | TCIF_IMAGE;
385    tci.pszText = szText;
386
387    for (int iTab = 0; iTab < nCHILDTABS; ++iTab)
388       {
389       tci.iImage = CHILDTABINFO[ iTab ].iImage;
390       tci.lParam = (LPARAM)CHILDTABINFO[ iTab ].tab;
391       GetString (tci.pszText, CHILDTABINFO[ iTab ].idsTabTitle);
392       TabCtrl_InsertItem (hTab, iTab, &tci);
393       }
394
395    // subclass the TCN_ window, so that it will start sending WM_SIZE
396    // messages to its child window.
397    //
398    procTabControl = GetWindowLongPtr (hTab, GWLP_WNDPROC);
399    SetWindowLongPtr (hTab, GWLP_WNDPROC, (LONG_PTR)Server_SubclassTabControlProc);
400
401    // Since we just subclassed this control, our new wndproc wasn't around
402    // when the window was created.  Any WM_CREATE processing we'd ordinarily
403    // in that wndproc must therefore be done here.
404
405    // WM_CREATE:
406    RECT rWindow;
407    GetRectInParent (hTab, &rWindow);
408    ResizeWindow (hTab, awdTabChild, rwaMoveToHere, &rWindow);
409
410    // Finally, select an appropriate tab and display it.
411    //
412    Server_DisplayTab (GetParent (hTab), gr.tabLast);
413 }
414
415
416 void Server_DisplayTab (HWND hDlg, CHILDTAB iTab)
417 {
418    HWND hTab = GetDlgItem (hDlg, IDC_TABS);
419    int idd = -1;
420    DLGPROC dlgproc = NULL;
421
422    switch (iTab)
423       {
424       case tabSERVICES:
425          idd = IDD_SERVICES;
426          dlgproc = (DLGPROC)Services_DlgProc;
427          break;
428       case tabAGGREGATES:
429          idd = IDD_AGGREGATES;
430          dlgproc = (DLGPROC)Aggregates_DlgProc;
431          break;
432       case tabFILESETS:
433          idd = IDD_FILESETS;
434          dlgproc = (DLGPROC)Filesets_DlgProc;
435          break;
436       }
437
438    if (idd != -1)
439       {
440       HWND hDialogOld = GetTabChild (hTab);
441       HWND hDialogNew = ModelessDialog (idd, hTab, dlgproc);
442
443       if (hDialogNew != NULL)
444          {
445          TabCtrl_SetCurSel (hTab, iTab);
446          ShowWindow (hDialogNew, SW_SHOW);
447
448          if (hDialogOld != NULL)
449             {
450             DestroyWindow (hDialogOld);
451             }
452
453          Server_ForceRedraw (hDlg);
454          }
455       }
456 }
457
458
459 void Server_Uncover (HWND hWnd)
460 {
461    if (hWnd == g.hMain) // uncover the preview pane?
462       {
463       AfsAppLib_Uncover (GetDlgItem (g.hMain, IDC_TABS));
464       }
465    else // uncover a standalone server window?
466       {
467       AfsAppLib_Uncover (hWnd);
468       }
469 }
470
471
472 void Server_SaveRect (HWND hDlg, BOOL fOpen)
473 {
474    LPSVR_SETWINDOWPOS_PARAMS lpp = New (SVR_SETWINDOWPOS_PARAMS);
475    GetWindowRect (hDlg, &lpp->rWindow);
476    lpp->lpi = Server_GetServer (hDlg);
477    lpp->fOpen = fOpen;
478
479    StartTask (taskSVR_SETWINDOWPOS, NULL, lpp);
480 }
481
482
483 BOOL Server_HandleDialogKeys (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
484 {
485    if (msg == WM_COMMAND)
486       {
487       switch (LOWORD(wp))
488          {
489          case M_KEY_RETURN:
490             Server_OnKey_Return();
491             return TRUE;
492
493          case M_KEY_CTRLTAB:
494             Server_OnKey_CtrlTab (hDlg, TRUE);
495             return TRUE;
496
497          case M_KEY_CTRLBACKTAB:
498             Server_OnKey_CtrlTab (hDlg, FALSE);
499             return TRUE;
500
501          case M_KEY_TAB:
502             Server_OnKey_Tab (hDlg, TRUE);
503             return TRUE;
504
505          case M_KEY_BACKTAB:
506             Server_OnKey_Tab (hDlg, FALSE);
507             return TRUE;
508
509          case M_KEY_MENU:
510             Server_OnKey_Menu();
511             return TRUE;
512
513          case M_KEY_ESC:
514             Server_OnKey_Esc();
515             return TRUE;
516
517          case M_KEY_PROPERTIES:
518             Server_OnKey_Properties();
519             return TRUE;
520          }
521       }
522
523    return FALSE;
524 }
525
526
527 void Server_OnKey_Return (void)
528 {
529    static NMHDR hdr;
530    hdr.hwndFrom = GetFocus();
531    hdr.idFrom = GetWindowLong (GetFocus(), GWL_ID);
532    hdr.code = FLN_LDBLCLICK;
533    PostMessage (GetParent (GetFocus()), WM_NOTIFY, 0, (LPARAM)&hdr);
534 }
535
536
537 void Server_OnKey_Menu (void)
538 {
539    HWND hFocus = GetFocus();
540    if (fIsFastList (hFocus))
541       {
542       POINT ptScreen = { 0, 0 };
543
544       HLISTITEM hItem;
545       if ((hItem = FastList_FindFirstSelected (hFocus)) != NULL)
546          {
547          FASTLISTITEMREGIONS reg;
548          FastList_GetItemRegions (hFocus, hItem, &reg);
549
550          ptScreen.x = reg.rItem.left + (reg.rItem.right -reg.rItem.left) /2;
551          ptScreen.y = reg.rItem.top + (reg.rItem.bottom -reg.rItem.top) /2;
552          ClientToScreen (GetFocus(), &ptScreen);
553          }
554
555       PostMessage (GetParent (GetFocus()), WM_CONTEXTMENU, (WPARAM)GetFocus(), MAKELONG(ptScreen.x,ptScreen.y));
556       }
557 }
558
559
560 void Server_OnKey_Esc (void)
561 {
562    HWND hFocus = GetFocus();
563    if (fIsFastList (hFocus))
564       {
565       FastList_SelectNone (hFocus);
566       }
567 }
568
569
570 void Server_OnKey_Properties (void)
571 {
572    HWND hFocus = GetFocus();
573    if (fIsFastList (hFocus))
574       {
575       LPIDENT lpi;
576       if ((lpi = (LPIDENT)FL_GetSelectedData (hFocus)) != NULL)
577          {
578          StartContextCommand (GetParent(hFocus), NULL, lpi, M_PROPERTIES);
579          }
580       }
581 }
582
583
584 void Server_OnKey_Tab (HWND hDlg, BOOL fForward)
585 {
586    // The tab-cycle should go:
587    //    TabControl <-> TabChildControls
588    //
589    HWND hFocus = GetFocus();
590    HWND hTabChild = GetTabChild (GetDlgItem (hDlg, IDC_TABS));
591
592    if (fForward)
593       {
594       if (hFocus == GetDlgItem (hDlg, IDC_TABS))
595          {
596          PostMessage (hDlg, WM_NEXTDLGCTL, (WPARAM)GetNextDlgTabItem (hTabChild, NULL, FALSE), TRUE);
597          }
598       else
599          {
600          if (GetNextDlgTabItem (hTabChild, hFocus, FALSE) == GetNextDlgTabItem (hTabChild, NULL, FALSE))
601             PostMessage (hDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem (hDlg, IDC_TABS), TRUE);
602          else
603             PostMessage (hDlg, WM_NEXTDLGCTL, (WPARAM)GetNextDlgTabItem (hTabChild, hFocus, FALSE), TRUE);
604          }
605       }
606    else // (!fForward)
607       {
608       if (hFocus == GetDlgItem (hDlg, IDC_TABS))
609          {
610          PostMessage (hDlg, WM_NEXTDLGCTL, (WPARAM)GetLastDlgTabItem (hTabChild), TRUE);
611          }
612       else
613          {
614          if (hFocus == GetNextDlgTabItem (hTabChild, NULL, FALSE))
615             PostMessage (hDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem (hDlg, IDC_TABS), TRUE);
616          else
617             PostMessage (hDlg, WM_NEXTDLGCTL, (WPARAM)GetNextDlgTabItem (hTabChild, hFocus, TRUE), TRUE);
618          }
619       }
620 }
621
622
623 void Server_OnKey_CtrlTab (HWND hDlg, BOOL fForward)
624 {
625    HWND hTabs = GetDlgItem (hDlg, IDC_TABS);
626    int iTab = TabCtrl_GetCurSel(hTabs);
627
628    if (fForward)
629       iTab = (iTab == nCHILDTABS-1) ? (0) : (iTab+1);
630    else
631       iTab = (iTab == 0) ? (nCHILDTABS-1) : (iTab-1);
632
633    TabCtrl_SetCurSel (hTabs, iTab);
634    Server_DisplayTab (hDlg, (CHILDTAB)iTab);
635    gr.tabLast = (CHILDTAB)iTab;
636
637    PostMessage (hDlg, WM_NEXTDLGCTL, (WPARAM)hTabs, TRUE);
638 }
639