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