windows-aklog-cleanup-20080321
[openafs.git] / src / WINNT / afssvrmgr / subset.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 "subset.h"
20 #include "propcache.h"
21
22
23 #define REGVAL_INCLUSIVE   TEXT("Inclusive List")
24
25 /*
26  * PROTOTYPES _________________________________________________________________
27  *
28  */
29
30 BOOL CALLBACK Subsets_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp);
31 void Subsets_OnInitDialog (HWND hDlg, LPSUBSET sub);
32 void Subsets_OnApply (HWND hDlg, LPSUBSET sub);
33 LPSUBSET Subsets_OnLoad (HWND hDlg, LPSUBSET sub);
34 void Subsets_OnSave (HWND hDlg, LPSUBSET sub);
35 void Subsets_SetName (HWND hDlg, LPSUBSET sub);
36 void Subsets_PutSubsetOnDialog (HWND hDlg, LPSUBSET sub);
37 void Subsets_GetSubsetFromDialog (HWND hDlg, LPSUBSET sub);
38 LPSUBSET Subsets_OnCheck (HWND hDlg, int iSel, LPSUBSET subOld);
39 LPSUBSET Subsets_OnCheckAll (HWND hDlg, LPSUBSET subOld, BOOL fCheck);
40
41 BOOL Subsets_GetLoadName (HWND hParent, LPTSTR pszSubset);
42 BOOL Subsets_GetSaveName (HWND hParent, LPTSTR pszSubset);
43
44
45 /*
46  * ROUTINES ___________________________________________________________________
47  *
48  */
49
50 BOOL Subsets_fMonitorServer (LPSUBSET sub, LPIDENT lpiServer)
51 {
52    BOOL fMonitor = TRUE;
53
54    TCHAR szLong[ cchNAME ];
55    TCHAR szShort[ cchNAME ];
56    lpiServer->GetLongServerName (szLong);
57    lpiServer->GetShortServerName (szShort);
58
59    if (sub)
60       {
61       if (sub->pszMonitored)
62          {
63          fMonitor = FALSE;  // unless it shows up here.
64
65          for (LPTSTR psz = sub->pszMonitored; !fMonitor && *psz; psz += 1+lstrlen(psz))
66             {
67             if (!lstrcmpi (psz, szLong))
68                fMonitor = TRUE;
69             else if (!lstrcmpi (psz, szShort))
70                fMonitor = TRUE;
71             }
72          }
73       else if (sub->pszUnmonitored)
74          {
75          for (LPTSTR psz = sub->pszUnmonitored; fMonitor && *psz; psz += 1+lstrlen(psz))
76             {
77             if (!lstrcmpi (psz, szLong))
78                fMonitor = FALSE;
79             else if (!lstrcmpi (psz, szShort))
80                fMonitor = FALSE;
81             }
82          }
83       }
84
85    return fMonitor;
86 }
87
88
89 LPSUBSET Subsets_SetMonitor (LPSUBSET sub, LPIDENT lpiServer, BOOL fMonitor)
90 {
91    if (sub == NULL)
92       {
93       sub = New (SUBSET);
94       memset (sub, 0x00, sizeof(SUBSET));
95       }
96
97    if (fMonitor != Subsets_fMonitorServer (sub, lpiServer))
98       {
99       sub->fModified = TRUE;
100
101       TCHAR szLong[ cchNAME ];
102       TCHAR szShort[ cchNAME ];
103       lpiServer->GetShortServerName (szShort);
104       lpiServer->GetLongServerName (szLong);
105
106       // First ensure that the server name doesn't appear anywhere
107       // in the subset.
108       //
109       LPTSTR pszMonitoredNew = NULL;
110       LPTSTR pszUnmonitoredNew = NULL;
111
112       if (sub->pszMonitored)
113          {
114          for (LPTSTR psz = sub->pszMonitored; *psz; psz += 1+lstrlen(psz))
115             {
116             if (lstrcmpi (psz, szLong) && lstrcmpi (psz, szShort))
117                {
118                FormatMultiString (&pszMonitoredNew, TRUE, TEXT("%1"), TEXT("%s"), psz);
119                }
120             }
121          }
122       else if (sub->pszUnmonitored)
123          {
124          for (LPTSTR psz = sub->pszUnmonitored; *psz; psz += 1+lstrlen(psz))
125             {
126             if (lstrcmpi (psz, szLong) && lstrcmpi (psz, szShort))
127                {
128                FormatMultiString (&pszUnmonitoredNew, TRUE, TEXT("%1"), TEXT("%s"), psz);
129                }
130             }
131          }
132
133       // Then ensure it shows up only where necessary.
134       //
135       if (sub->pszMonitored && fMonitor)
136          {
137          FormatMultiString (&pszMonitoredNew, TRUE, TEXT("%1"), TEXT("%s"), szLong);
138          }
139       else if (!sub->pszMonitored && !fMonitor)
140          {
141          FormatMultiString (&pszUnmonitoredNew, TRUE, TEXT("%1"), TEXT("%s"), szLong);
142          }
143
144       if (sub->pszMonitored && !pszMonitoredNew)
145          {
146          pszMonitoredNew = AllocateString (2);
147          pszMonitoredNew[0] = TEXT('\0');
148          pszMonitoredNew[1] = TEXT('\0');
149          }
150       if (sub->pszUnmonitored && !pszUnmonitoredNew)
151          {
152          pszUnmonitoredNew = AllocateString (2);
153          pszUnmonitoredNew[0] = TEXT('\0');
154          pszUnmonitoredNew[1] = TEXT('\0');
155          }
156
157       // Finally, update the subset's members.
158       //
159       if (sub->pszMonitored)
160          FreeString (sub->pszMonitored);
161       if (sub->pszUnmonitored)
162          FreeString (sub->pszUnmonitored);
163
164       sub->pszMonitored = pszMonitoredNew;
165       sub->pszUnmonitored = pszUnmonitoredNew;
166       }
167
168    return sub;
169 }
170
171
172 void ShowSubsetsDialog (void)
173 {
174    LPPROPSHEET psh = PropSheet_Create (IDS_SUBSET_TAB, FALSE);
175    psh->sh.hwndParent = g.hMain;
176
177    LPSUBSET sub = Subsets_CopySubset (g.sub);
178    PropSheet_AddTab (psh, 0, IDD_SUBSETS, (DLGPROC)Subsets_DlgProc, (LPARAM)sub, TRUE);
179    PropSheet_ShowModal (psh, PumpMessage);
180 }
181
182
183 BOOL CALLBACK Subsets_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
184 {
185    if (AfsAppLib_HandleHelp (IDD_SUBSETS, hDlg, msg, wp, lp))
186       return TRUE;
187
188    if (msg == WM_INITDIALOG)
189       SetWindowLongPtr (hDlg, DWLP_USER, ((LPPROPSHEETPAGE)lp)->lParam);
190
191    LPSUBSET sub = (LPSUBSET)GetWindowLongPtr (hDlg, DWLP_USER);
192
193    switch (msg)
194       {
195       case WM_INITDIALOG_SHEET:
196          PropCache_Add (pcGENERAL, NULL, hDlg);
197          break;
198
199       case WM_DESTROY_SHEET:
200          PropCache_Delete (hDlg);
201          break;
202
203       case WM_INITDIALOG:
204          Subsets_OnInitDialog (hDlg, sub);
205          break;
206
207       case WM_COMMAND:
208          switch (LOWORD(wp))
209             {
210             case IDAPPLY:
211                Subsets_OnApply (hDlg, sub);
212                break;
213
214             case IDOK:
215             case IDCANCEL:
216                EndDialog (hDlg, LOWORD(wp));
217                break;
218
219             case IDC_SUBSET_LOAD:
220                LPSUBSET subNew;
221                subNew = Subsets_OnLoad (hDlg, sub);
222                if (subNew != NULL)
223                   {
224                   if (sub)
225                      Subsets_FreeSubset (sub);
226                   SetWindowLongPtr (hDlg, DWLP_USER, (LONG_PTR)subNew);
227                   }
228                break;
229
230             case IDC_SUBSET_LIST:
231                if (HIWORD(wp) == LBN_CLICKED)  // checked or unchecked?
232                   {
233                   int iSel = LB_GetSelected (GetDlgItem (hDlg, IDC_SUBSET_LIST));
234                   subNew = Subsets_OnCheck (hDlg, iSel, sub);
235                   if (subNew && (subNew != sub))
236                      {
237                      if (sub)
238                         Subsets_FreeSubset (sub);
239                      SetWindowLongPtr (hDlg, DWLP_USER, (LONG_PTR)subNew);
240                      }
241                   }
242                break;
243
244             case IDC_SUBSET_SAVE:
245                Subsets_OnSave (hDlg, sub);
246                break;
247
248             case IDC_SUBSET_ALL:
249             case IDC_SUBSET_NONE:
250                subNew = Subsets_OnCheckAll (hDlg, sub, (LOWORD(wp) == IDC_SUBSET_ALL) ? TRUE : FALSE);
251                if (subNew && (subNew != sub))
252                   {
253                   if (sub)
254                      Subsets_FreeSubset (sub);
255                   SetWindowLongPtr (hDlg, DWLP_USER, (LONG_PTR)subNew);
256                   }
257                break;
258             }
259          break;
260       }
261
262    return FALSE;
263 }
264
265
266 void Subsets_OnInitDialog (HWND hDlg, LPSUBSET sub)
267 {
268    Subsets_SetName (hDlg, sub);
269    Subsets_PutSubsetOnDialog (hDlg, sub);
270 }
271
272
273 void Subsets_SetName (HWND hDlg, LPSUBSET sub)
274 {
275    LPTSTR pszText;
276
277    BOOL fIsOneServer = FALSE;
278    if (sub && sub->pszMonitored && *(sub->pszMonitored))
279       {
280       LPTSTR pszNext = &sub->pszMonitored[ 1+lstrlen(sub->pszMonitored) ];
281       if (!*pszNext)
282          fIsOneServer = TRUE;
283       }
284
285    if (sub && sub->szSubset[0])
286       {
287       if (sub->fModified)
288          pszText = FormatString (IDS_SUBSET_CHANGED, TEXT("%s"), sub->szSubset);
289       else
290          pszText = FormatString (TEXT("%1"), TEXT("%s"), sub->szSubset);
291       }
292    else if (fIsOneServer)
293       {
294       pszText = FormatString (IDS_SUBSET_SERVERSUBSET, TEXT("%s"), sub->pszMonitored);
295       }
296    else if (sub) // && !sub->szSubset[0]
297       {
298       if (sub->fModified)
299          pszText = FormatString (IDS_SUBSET_CHANGED, TEXT("%m"), IDS_SUBSET_NONAME);
300       else
301          pszText = FormatString (TEXT("%1"), TEXT("%m"), IDS_SUBSET_NONAME);
302       }
303    else // no current subset specified
304       {
305       pszText = FormatString (TEXT("%1"), TEXT("%m"), IDS_SUBSET_NOSUBSET);
306       }
307
308    SetDlgItemText (hDlg, IDC_SUBSET_NAME, pszText);
309    FreeString (pszText);
310 }
311
312
313 void Subsets_PutSubsetOnDialog (HWND hDlg, LPSUBSET sub)
314 {
315    LPSUBSET_TO_LIST_PACKET lpp = New (SUBSET_TO_LIST_PACKET);
316    memset (lpp, 0x00, sizeof(SUBSET_TO_LIST_PACKET));
317
318    lpp->hList = GetDlgItem (hDlg, IDC_SUBSET_LIST);
319    lpp->sub = Subsets_CopySubset (sub);
320
321    StartTask (taskSUBSET_TO_LIST, NULL, lpp);
322 }
323
324
325 void Subsets_GetSubsetFromDialog (HWND hDlg, LPSUBSET sub)
326 {
327    HWND hList = GetDlgItem (hDlg, IDC_SUBSET_LIST);
328
329    if (sub->pszMonitored)
330       {
331       FreeString (sub->pszMonitored);
332       sub->pszMonitored = NULL;
333       }
334    if (sub->pszUnmonitored)
335       {
336       FreeString (sub->pszUnmonitored);
337       sub->pszUnmonitored = NULL;
338       }
339
340    // Is there only one server box checked?
341    //
342    int iiMax = (int) SendMessage (hList, LB_GETCOUNT, 0, 0);
343
344    size_t cChecked = 0;
345    int iiChecked;
346    for (int ii = 0; ii < iiMax; ++ii)
347       {
348       if (LB_GetCheck (hList, ii))
349          {
350          iiChecked = ii;
351          if ((++cChecked) > 1)
352             break;
353          }
354       }
355    if (cChecked == 1)  // Only one is checked--use pszMonitored.
356       {
357       TCHAR szServer[ cchNAME ];
358       SendMessage (hList, LB_GETTEXT, iiChecked, (LPARAM)szServer); 
359       FormatMultiString (&sub->pszMonitored, TRUE, TEXT("%1"), TEXT("%s"), szServer);
360       }
361    else // Use pszUnmonitored.
362       {
363       for (int ii = 0; ii < iiMax; ++ii)
364          {
365          if (!LB_GetCheck (hList, ii))
366             {
367             TCHAR szServer[ cchNAME ];
368             SendMessage (hList, LB_GETTEXT, ii, (LPARAM)szServer); 
369             FormatMultiString (&sub->pszUnmonitored, TRUE, TEXT("%1"), TEXT("%s"), szServer);
370             }
371          }
372       }
373 }
374
375
376 LPSUBSET Subsets_OnCheck (HWND hDlg, int iSel, LPSUBSET subOld)
377 {
378    LPSUBSET sub = subOld;
379    HWND hList = GetDlgItem (hDlg, IDC_SUBSET_LIST);
380
381    if (!LB_GetCheck (hList, iSel))  // unchecked?
382       {
383       if (!sub)
384          {
385          sub = New (SUBSET);
386          memset (sub, 0x00, sizeof(SUBSET));
387          }
388       }
389
390    if (sub)
391       {
392       sub->fModified = TRUE;
393       Subsets_GetSubsetFromDialog (hDlg, sub);
394       Subsets_SetName (hDlg, sub);
395       PropSheetChanged (hDlg);
396       }
397
398    return sub;
399 }
400
401
402 LPSUBSET Subsets_OnCheckAll (HWND hDlg, LPSUBSET subOld, BOOL fCheck)
403 {
404    LPSUBSET sub = subOld;
405    HWND hList = GetDlgItem (hDlg, IDC_SUBSET_LIST);
406
407    if (!fCheck)  // unchecking things?
408       {
409       if (!sub)
410          {
411          sub = New (SUBSET);
412          memset (sub, 0x00, sizeof(SUBSET));
413          }
414       }
415
416    int iiMax = (int) SendMessage (hList, LB_GETCOUNT, 0, 0);
417
418    for (int ii = 0; ii < iiMax; ++ii)
419       {
420       if (LB_GetCheck (hList, ii) != fCheck)
421          {
422          LB_SetCheck (hList, ii, fCheck);
423          }
424       }
425
426    if (sub)
427       {
428       sub->fModified = TRUE;
429       Subsets_GetSubsetFromDialog (hDlg, sub);
430       Subsets_SetName (hDlg, sub);
431       PropSheetChanged (hDlg);
432       }
433
434    return sub;
435 }
436
437
438 LPSUBSET Subsets_OnLoad (HWND hDlg, LPSUBSET subOld)
439 {
440    LPSUBSET subNew = NULL;
441
442    TCHAR szSubset[ cchNAME ] = TEXT("");
443    if (subOld)
444       lstrcpy (szSubset, subOld->szSubset);
445
446    if (Subsets_GetLoadName (hDlg, szSubset))
447       {
448       if ((subNew = Subsets_LoadSubset (NULL, szSubset)) != NULL)
449          {
450          Subsets_SetName (hDlg, subNew);
451          Subsets_PutSubsetOnDialog (hDlg, subNew);
452          PropSheetChanged (hDlg);
453          }
454       }
455
456    return subNew;
457 }
458
459
460 void Subsets_OnSave (HWND hDlg, LPSUBSET sub)
461 {
462    if (sub)
463       {
464       TCHAR szSubset[ cchNAME ];
465       lstrcpy (szSubset, sub->szSubset);
466
467       if (Subsets_GetSaveName (hDlg, szSubset))
468          {
469          Subsets_GetSubsetFromDialog (hDlg, sub);
470
471          if (Subsets_SaveSubset (NULL, szSubset, sub))
472             {
473             lstrcpy (sub->szSubset, szSubset);
474             sub->fModified = FALSE;
475
476             Subsets_SetName (hDlg, sub);
477             }
478          }
479       }
480 }
481
482
483 void Subsets_OnApply (HWND hDlg, LPSUBSET sub)
484 {
485    LPSUBSET subCopy;
486    if ((subCopy = Subsets_CopySubset (sub, TRUE)) != NULL)
487       {
488       Subsets_GetSubsetFromDialog (hDlg, subCopy);
489       }
490
491    LPSUBSET subOld = g.sub;
492    g.sub = subCopy;
493    if (subOld)
494       Subsets_FreeSubset (subOld);
495
496    StartTask (taskAPPLY_SUBSET, NULL, sub);
497 }
498
499
500 BOOL Subsets_SaveIfDirty (LPSUBSET sub)
501 {
502    if (!sub || !sub->fModified)
503       return TRUE;
504
505    int rc;
506    rc = Message (MB_YESNOCANCEL | MB_ICONQUESTION, IDS_SUBSET_DISCARD_TITLE, IDS_SUBSET_DISCARD_DESC);
507
508    if (rc == IDNO)
509       {
510       sub->fModified = FALSE;
511       sub->szSubset[0] = TEXT('\0');
512       }
513    else if (rc == IDYES)
514       {
515       TCHAR szSubset[ cchNAME ];
516       lstrcpy (szSubset, sub->szSubset);
517
518       if (!Subsets_GetSaveName (g.hMain, szSubset))
519          return FALSE;
520
521       if (!Subsets_SaveSubset (NULL, szSubset, sub))
522          return FALSE;
523
524       sub->fModified = FALSE;
525       lstrcpy (sub->szSubset, szSubset);
526       }
527    else // (rc == IDCANCEL)
528       {
529       return FALSE;
530       }
531
532    return TRUE;
533 }
534
535
536 BOOL Subsets_EnumSubsets (LPTSTR pszCell, size_t iIndex, LPTSTR pszSubset)
537 {
538    BOOL rc = FALSE;
539
540    HKEY hk;
541    if ((hk = OpenSubsetsKey (pszCell, FALSE)) != NULL)
542       {
543       if (RegEnumKey (hk, (DWORD)iIndex, pszSubset, cchNAME) == 0)
544          rc = TRUE;
545
546       RegCloseKey (hk);
547       }
548
549    return rc;
550 }
551
552
553 BOOL Subsets_SaveSubset (LPTSTR pszCell, LPTSTR pszSubset, LPSUBSET sub)
554 {
555    BOOL rc = FALSE;
556
557    if (sub && pszSubset && *pszSubset)
558       {
559       HKEY hk;
560       if ((hk = OpenSubsetsSubKey (pszCell, pszSubset, TRUE)) != NULL)
561          {
562          DWORD dwMonitored = (sub->pszMonitored) ? 1 : 0;
563          RegSetValueEx (hk, REGVAL_INCLUSIVE, 0, REG_DWORD, (LPBYTE)&dwMonitored, sizeof(DWORD));
564
565          for (LPTSTR psz = (sub->pszMonitored) ? sub->pszMonitored : sub->pszUnmonitored;
566               psz && *psz;
567               psz += 1+lstrlen(psz))
568             {
569             RegSetValueEx (hk, psz, 0, REG_SZ, (PBYTE)TEXT("X"), sizeof(TCHAR)*2);
570             }
571
572          rc = TRUE;
573
574          RegCloseKey (hk);
575          }
576       }
577
578    return rc;
579 }
580
581
582 LPSUBSET Subsets_LoadSubset (LPTSTR pszCell, LPTSTR pszSubset)
583 {
584    LPSUBSET sub = NULL;
585
586    HKEY hk;
587    if ((hk = OpenSubsetsSubKey (pszCell, pszSubset, FALSE)) != NULL)
588       {
589       DWORD dwMonitored;
590       DWORD dwSize;
591       DWORD dwType;
592       dwSize = sizeof(dwMonitored);
593       if (RegQueryValueEx (hk, REGVAL_INCLUSIVE, 0, &dwType, (LPBYTE)&dwMonitored, &dwSize) == 0)
594          {
595          sub = New (SUBSET);
596          memset (sub, 0x00, sizeof(SUBSET));
597          lstrcpy (sub->szSubset, pszSubset);
598          sub->fModified = FALSE;
599
600          LPTSTR *ppsz;
601          ppsz = (dwMonitored) ? &sub->pszMonitored : &sub->pszUnmonitored;
602
603          for (size_t iIndex = 0; ; ++iIndex)
604             {
605             TCHAR szServer[ cchNAME ];
606             dwSize = sizeof(szServer);
607
608             if (RegEnumValue (hk, (DWORD)iIndex, szServer, &dwSize, 0, NULL, NULL, NULL) != 0)
609                break;
610
611             if (szServer[0] && lstrcmpi (szServer, REGVAL_INCLUSIVE))
612                FormatMultiString (ppsz, FALSE, TEXT("%1"), TEXT("%s"), szServer);
613             }
614
615          if (dwMonitored && !sub->pszMonitored)
616             {
617             sub->pszMonitored = AllocateString(2);
618             sub->pszMonitored[0] = TEXT('\0');
619             sub->pszMonitored[1] = TEXT('\0');
620             }
621          }
622
623       RegCloseKey (hk);
624       }
625
626    return sub;
627 }
628
629
630 LPSUBSET Subsets_CopySubset (LPSUBSET sub, BOOL fCreateIfNULL)
631 {
632    LPSUBSET subCopy = NULL;
633
634    if (sub != NULL)
635       {
636       subCopy = New (SUBSET);
637       memset (subCopy, 0x00, sizeof(SUBSET));
638       lstrcpy (subCopy->szSubset, sub->szSubset);
639       subCopy->fModified = sub->fModified;
640
641       size_t cch;
642       if (sub->pszMonitored)
643          {
644          cch = 1;
645          for (LPTSTR psz = sub->pszMonitored; *psz; psz += 1+lstrlen(psz))
646             cch += 1+lstrlen(psz);
647          subCopy->pszMonitored = AllocateString (cch);
648          memcpy (subCopy->pszMonitored, sub->pszMonitored, sizeof(TCHAR)*cch);
649          }
650
651       if (sub->pszUnmonitored)
652          {
653          cch = 1;
654          for (LPTSTR psz = sub->pszUnmonitored; *psz; psz += 1+lstrlen(psz))
655             cch += 1+lstrlen(psz);
656          subCopy->pszUnmonitored = AllocateString (cch);
657          memcpy (subCopy->pszUnmonitored, sub->pszUnmonitored, sizeof(TCHAR)*cch);
658          }
659       }
660    else if (fCreateIfNULL)
661       {
662       subCopy = New (SUBSET);
663       memset (subCopy, 0x00, sizeof(SUBSET));
664       }
665
666    return subCopy;
667 }
668
669
670 void Subsets_FreeSubset (LPSUBSET sub)
671 {
672    if (sub != NULL)
673       {
674       if (sub->pszMonitored)
675          FreeString (sub->pszMonitored);
676       if (sub->pszUnmonitored)
677          FreeString (sub->pszUnmonitored);
678
679       Delete (sub);
680       }
681 }
682
683
684 /*
685  * SUBSET OPEN/SAVE DIALOG ____________________________________________________
686  *
687  */
688
689 typedef struct
690    {
691    BOOL fOpen;
692    TCHAR szCell[ cchNAME ];
693    TCHAR szSubset[ cchNAME ];
694    } SUBSET_OPENSAVE_PARAMS, *LPSUBSET_OPENSAVE_PARAMS;
695
696 BOOL CALLBACK Subsets_OpenSave_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp);
697 void Subsets_OpenSave_OnInitDialog (HWND hDlg, LPSUBSET_OPENSAVE_PARAMS lpp);
698 void Subsets_OpenSave_OnSelect (HWND hDlg);
699 void Subsets_OpenSave_Populate (HWND hDlg);
700 void Subsets_OpenSave_OnDelete (HWND hDlg);
701 void Subsets_OpenSave_OnRename (HWND hDlg);
702
703
704 BOOL Subsets_GetLoadName (HWND hParent, LPTSTR pszSubset)
705 {
706    SUBSET_OPENSAVE_PARAMS lpp;
707    lpp.fOpen = TRUE;
708    lpp.szCell[0] = TEXT('\0');
709    lstrcpy (lpp.szSubset, pszSubset);
710
711    if (g.lpiCell)
712       g.lpiCell->GetCellName (lpp.szCell);
713
714    INT_PTR rc = ModalDialogParam (IDD_SUBSET_LOADSAVE,
715                           hParent, (DLGPROC)Subsets_OpenSave_DlgProc,
716                           (LPARAM)&lpp);
717
718    if (rc == IDOK)
719       {
720       lstrcpy (pszSubset, lpp.szSubset);
721       }
722
723    return (rc == IDOK) ? TRUE : FALSE;
724 }
725
726
727 BOOL Subsets_GetSaveName (HWND hParent, LPTSTR pszSubset)
728 {
729    SUBSET_OPENSAVE_PARAMS lpp;
730    lpp.fOpen = FALSE;
731    lpp.szCell[0] = TEXT('\0');
732    lstrcpy (lpp.szSubset, pszSubset);
733
734    if (g.lpiCell)
735       g.lpiCell->GetCellName (lpp.szCell);
736
737    INT_PTR rc = ModalDialogParam (IDD_SUBSET_LOADSAVE,
738                           hParent, (DLGPROC)Subsets_OpenSave_DlgProc,
739                           (LPARAM)&lpp);
740
741    if (rc == IDOK)
742       {
743       lstrcpy (pszSubset, lpp.szSubset);
744       }
745
746    return (rc == IDOK) ? TRUE : FALSE;
747 }
748
749
750 BOOL CALLBACK Subsets_OpenSave_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
751 {
752    static BOOL fEditing = FALSE;
753
754    if (msg == WM_INITDIALOG)
755       SetWindowLongPtr (hDlg, DWLP_USER, lp);
756
757    LPSUBSET_OPENSAVE_PARAMS lpp;
758    if ((lpp = (LPSUBSET_OPENSAVE_PARAMS)GetWindowLongPtr (hDlg, DWLP_USER)) != NULL)
759       {
760       switch (msg)
761          {
762          case WM_INITDIALOG:
763             fEditing = FALSE;
764             Subsets_OpenSave_OnInitDialog (hDlg, lpp);
765             break;
766
767          case WM_COMMAND:
768             if (!fEditing)
769                {
770                switch (LOWORD(wp))
771                   {
772                   case IDCANCEL:
773                      EndDialog (hDlg, IDCANCEL);
774                      break;
775
776                   case IDOK:
777                      GetDlgItemText (hDlg, IDC_SUBSET_NAME, lpp->szSubset, cchNAME);
778                      if (lpp->szSubset[0] != TEXT('\0'))
779                         {
780                         BOOL fClose = TRUE;
781
782                         if (!lpp->fOpen)
783                            {
784                            HKEY hk;
785                            if ((hk = OpenSubsetsSubKey (NULL, lpp->szSubset, FALSE)) != NULL)
786                               {
787                               RegCloseKey (hk);
788
789                               int rc = Message (MB_YESNO | MB_ICONASTERISK, IDS_SUBSET_SAVE_TITLE, IDS_SUBSET_SAVE_DESC, TEXT("%s"), lpp->szSubset);
790                               if (rc != IDYES)
791                                  fClose = FALSE;
792                               }
793                            }
794
795                         if (fClose)
796                            EndDialog (hDlg, IDOK);
797                         }
798                      break;
799
800                   case IDC_SUBSET_DELETE:
801                      Subsets_OpenSave_OnDelete (hDlg);
802                      break;
803
804                   case IDC_SUBSET_RENAME:
805                      Subsets_OpenSave_OnRename (hDlg);
806                      break;
807                   }
808                }
809             break;
810
811          case WM_NOTIFY:
812             switch (((LPNMHDR)lp)->code)
813                {
814                case LVN_ITEMCHANGED:
815                   if (!fEditing)
816                      {
817                      if ( ((LPNM_LISTVIEW)lp)->uNewState & LVIS_SELECTED )
818                         Subsets_OpenSave_OnSelect (hDlg);
819                      }
820                   break;
821
822                case NM_DBLCLK:
823                   if (!fEditing)
824                      {
825                      if (((LPNMHDR)lp)->hwndFrom == GetDlgItem (hDlg, IDC_SUBSET_LIST))
826                         {
827                         Subsets_OpenSave_OnSelect (hDlg);
828                         PostMessage (hDlg, WM_COMMAND, IDOK, 0);
829                         }
830                      }
831                   break;
832
833                case LVN_BEGINLABELEDIT:
834                   fEditing = TRUE;
835                   return FALSE;  // okay to edit label
836
837                case LVN_ENDLABELEDIT:
838                   LV_DISPINFO *plvdi;
839                   if ((plvdi = (LV_DISPINFO*)lp) != NULL)
840                      {
841                      if ((plvdi->item.iItem != -1) &&
842                          (plvdi->item.pszText != NULL))
843                         {
844                         HWND hList = GetDlgItem (hDlg, IDC_SUBSET_LIST);
845                         TCHAR szOldName[ cchNAME ];
846                         LV_GetItemText (hList, plvdi->item.iItem, 0, szOldName);
847
848                         if (lstrcmpi (szOldName, plvdi->item.pszText))
849                            {
850                            BOOL fRename = TRUE;
851                            BOOL fRepopulate = FALSE;
852
853                            HKEY hk;
854                            if ((hk = OpenSubsetsSubKey (NULL, plvdi->item.pszText, FALSE)) != NULL)
855                               {
856                               RegCloseKey (hk);
857
858                               int rc = Message (MB_YESNO | MB_ICONASTERISK, IDS_SUBSET_SAVE_TITLE, IDS_SUBSET_SAVE_DESC, TEXT("%s"), lpp->szSubset);
859                               if (rc != IDYES)
860                                  fRename = FALSE;
861                               else
862                                  fRepopulate = TRUE;
863                               }
864
865                            if (fRename)
866                               {
867                               LPSUBSET subRename;
868                               if ((subRename = Subsets_LoadSubset (NULL, szOldName)) != NULL)
869                                  {
870                                  if (Subsets_SaveSubset (NULL, plvdi->item.pszText, subRename))
871                                     {
872                                     (void)OpenSubsetsSubKey (NULL, szOldName, 2); // 0=open,1=create,2=delete
873
874                                     if (fRepopulate)
875                                        Subsets_OpenSave_Populate (hDlg);
876                                     else
877                                        {
878                                        LV_SetItemText (hList, plvdi->item.iItem, 0, plvdi->item.pszText);
879                                        Subsets_OpenSave_OnSelect (hDlg);
880                                        }
881
882                                     Subsets_FreeSubset (subRename);
883                                     }
884                                  }
885                               }
886                            }
887                         }
888                      }
889
890                   fEditing = FALSE;
891                   break;
892                }
893             break;
894          }
895       }
896
897    return FALSE;
898 }
899
900
901 void Subsets_OpenSave_OnInitDialog (HWND hDlg, LPSUBSET_OPENSAVE_PARAMS lpp)
902 {
903    // Fix the buttons in the toolbar, so that they looks pretty
904    //
905    HWND hButton = GetDlgItem (hDlg, IDC_SUBSET_DELETE);
906    HICON hi = TaLocale_LoadIcon (IDI_BTN_DELETE);
907    SendMessage (hButton, BM_SETIMAGE, (WPARAM)IMAGE_ICON, (LPARAM)hi);
908
909    hButton = GetDlgItem (hDlg, IDC_SUBSET_RENAME);
910    hi = TaLocale_LoadIcon (IDI_BTN_RENAME);
911    SendMessage (hButton, BM_SETIMAGE, (WPARAM)IMAGE_ICON, (LPARAM)hi);
912
913    // Set up an ImageList so we'll have icons in the ListView
914    //
915    HWND hList = GetDlgItem (hDlg, IDC_SUBSET_LIST);
916    HIMAGELIST hil = ImageList_Create (16, 16, ILC_COLOR4 | ILC_MASK, 1, 1);
917
918    hi = TaLocale_LoadIcon (IDI_SUBSET);
919    ImageList_AddIcon (hil, hi);
920
921    ListView_SetImageList (hList, hil, LVSIL_SMALL);
922
923    // Then populate the ListView with the names of the subsets
924    // defined for this cell
925    //
926    Subsets_OpenSave_Populate (hDlg);
927    // Finally, fill in the rest of the dialog.
928    //
929    SetDlgItemText (hDlg, IDC_SUBSET_NAME, lpp->szSubset);
930
931    TCHAR szText[ cchRESOURCE ];
932    GetString (szText, (lpp->fOpen) ? IDS_SUBSET_TITLE_LOAD : IDS_SUBSET_TITLE_SAVE);
933    SetWindowText (hDlg, szText);
934
935    GetString (szText, (lpp->fOpen) ? IDS_BUTTON_OPEN : IDS_BUTTON_SAVE);
936    SetDlgItemText (hDlg, IDOK, szText);
937 }
938
939
940 void Subsets_OpenSave_Populate (HWND hDlg)
941 {
942    HWND hList = GetDlgItem (hDlg, IDC_SUBSET_LIST);
943    LV_StartChange (hList, TRUE);
944
945    TCHAR szSubset[ cchNAME ];
946    for (size_t iIndex = 0; Subsets_EnumSubsets (NULL, iIndex, szSubset); ++iIndex)
947       {
948       LV_AddItem (hList, 1, 0, 0, 0, szSubset);
949       }
950
951    LV_EndChange (hList);
952 }
953
954
955 void Subsets_OpenSave_OnSelect (HWND hDlg)
956 {
957    TCHAR szSubset[ cchNAME ];
958
959    HWND hList = GetDlgItem (hDlg, IDC_SUBSET_LIST);
960    short idxSelected = LV_GetSelected (hList);
961
962    if (idxSelected == -1)
963       szSubset[0] = TEXT('\0');
964    else
965       LV_GetItemText (hList, idxSelected, 0, szSubset);
966
967    SetDlgItemText (hDlg, IDC_SUBSET_NAME, szSubset);
968 }
969
970
971 void Subsets_OpenSave_OnDelete (HWND hDlg)
972 {
973    HWND hList = GetDlgItem (hDlg, IDC_SUBSET_LIST);
974    short idxSelected = LV_GetSelected (hList);
975
976    if (idxSelected != -1)
977       {
978       TCHAR szSubset[ cchNAME ];
979       LV_GetItemText (hList, idxSelected, 0, szSubset);
980
981       if (Message (MB_ICONASTERISK | MB_YESNO, IDS_SUBSET_DELETE_TITLE, IDS_SUBSET_DELETE_DESC, TEXT("%s"), szSubset) == IDYES)
982          {
983          (void)OpenSubsetsSubKey (NULL, szSubset, 2); // 0=open,1=create,2=delete
984          Subsets_OpenSave_Populate (hDlg);
985          }
986       }
987 }
988
989
990 void Subsets_OpenSave_OnRename (HWND hDlg)
991 {
992    HWND hList = GetDlgItem (hDlg, IDC_SUBSET_LIST);
993    short idxSelected = LV_GetSelected (hList);
994
995    if (idxSelected != -1)
996       {
997       SetFocus (hList);
998       ListView_EditLabel (hList, idxSelected);
999       }
1000 }
1001