Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

466 lines
13 KiB

  1. /****************************************************************************
  2. Copyright (c) 1998-1999 Microsoft Corporation
  3. Module Name: cplareacodedlg.cpp
  4. Author: toddb - 10/06/98
  5. ****************************************************************************/
  6. #include "cplPreComp.h"
  7. #include "cplAreaCodeDlg.h"
  8. #include "cplSimpleDialogs.h"
  9. CAreaCodeRuleDialog::CAreaCodeRuleDialog(BOOL bNew, CAreaCodeRule * pRule)
  10. {
  11. m_bNew = bNew;
  12. m_pRule = pRule;
  13. m_iSelectedItem = -1;
  14. }
  15. CAreaCodeRuleDialog::~CAreaCodeRuleDialog()
  16. {
  17. }
  18. INT_PTR CAreaCodeRuleDialog::DoModal(HWND hwndParent)
  19. {
  20. return DialogBoxParam( GetUIInstance(), MAKEINTRESOURCE(IDD_NEWAREACODERULE), hwndParent, CAreaCodeRuleDialog::DialogProc, (LPARAM)this );
  21. }
  22. INT_PTR CALLBACK CAreaCodeRuleDialog::DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  23. {
  24. CAreaCodeRuleDialog * pthis = (CAreaCodeRuleDialog *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
  25. switch (uMsg)
  26. {
  27. case WM_INITDIALOG:
  28. pthis = (CAreaCodeRuleDialog *)lParam;
  29. SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) pthis);
  30. return pthis->OnInitDialog(hwndDlg);
  31. case WM_COMMAND:
  32. return pthis->OnCommand(hwndDlg, LOWORD(wParam), HIWORD(wParam), (HWND)lParam);
  33. case WM_NOTIFY:
  34. return pthis->OnNotify(hwndDlg, (LPNMHDR)lParam);
  35. case WM_HELP:
  36. TapiCplWinHelp ((HWND)((LPHELPINFO)lParam)->hItemHandle, gszHelpFile, HELP_WM_HELP, (DWORD_PTR)(LPTSTR) a109HelpIDs);
  37. break;
  38. case WM_CONTEXTMENU:
  39. // Process right-clicks on controls
  40. TapiCplWinHelp ((HWND)wParam, gszHelpFile, HELP_CONTEXTMENU, (DWORD_PTR)(LPVOID) a109HelpIDs);
  41. }
  42. return 0;
  43. }
  44. void CAreaCodeRuleDialog::PopulatePrefixList(HWND hwndList)
  45. {
  46. TCHAR szText[MAX_INPUT];
  47. LVITEM lvi;
  48. lvi.mask = LVIF_TEXT;
  49. lvi.iItem = 0;
  50. lvi.iSubItem = 0;
  51. lvi.pszText = szText;
  52. int i;
  53. LPWSTR pszz = m_pRule->GetPrefixList();
  54. if (pszz)
  55. {
  56. while (*pszz)
  57. {
  58. SHUnicodeToTChar( pszz, szText, ARRAYSIZE(szText) );
  59. ListView_InsertItem(hwndList, &lvi);
  60. pszz += lstrlenW(pszz)+1;
  61. }
  62. }
  63. }
  64. void CAreaCodeRuleDialog::SetPrefixControlsState(HWND hwndDlg, BOOL bAll)
  65. {
  66. HWND hwndList = GetDlgItem(hwndDlg,IDC_PREFIXES);
  67. EnableWindow(hwndList, !bAll);
  68. hwndList = GetDlgItem(hwndDlg, IDC_LIST);
  69. EnableWindow(hwndList, !bAll);
  70. EnableWindow(GetDlgItem(hwndDlg,IDC_ADD), !bAll);
  71. // by default, no prefix is selected so the remove button is always disabled at first
  72. if (m_iSelectedItem == -1)
  73. {
  74. m_iSelectedItem = 0;
  75. }
  76. EnableWindow(GetDlgItem(hwndDlg,IDC_REMOVE), ListView_GetItemCount(hwndList) && !bAll);
  77. if (!bAll)
  78. {
  79. ListView_SetItemState(hwndList, m_iSelectedItem, LVIS_FOCUSED|LVIS_SELECTED, LVIS_FOCUSED|LVIS_SELECTED);
  80. }
  81. }
  82. BOOL CAreaCodeRuleDialog::OnInitDialog(HWND hwndDlg)
  83. {
  84. HWND hwnd;
  85. TCHAR szText[MAX_INPUT];
  86. if ( !m_bNew )
  87. {
  88. LoadString(GetUIInstance(),IDS_EDITRULE, szText, ARRAYSIZE(szText));
  89. SetWindowText(hwndDlg, szText);
  90. }
  91. hwnd = GetDlgItem(hwndDlg,IDC_AREACODE);
  92. SHUnicodeToTChar(m_pRule->GetAreaCode(), szText, ARRAYSIZE(szText));
  93. SetWindowText(hwnd, szText);
  94. SendMessage(hwnd, EM_SETLIMITTEXT, CPL_SETTEXTLIMIT, 0);
  95. LimitInput(hwnd, LIF_ALLOWNUMBER);
  96. BOOL bAll = m_pRule->HasAppliesToAllPrefixes();
  97. CheckRadioButton(hwndDlg, IDC_ALLPREFIXES, IDC_LISTEDPREFIXES, bAll?IDC_ALLPREFIXES:IDC_LISTEDPREFIXES);
  98. // populate the prefix list
  99. hwnd = GetDlgItem(hwndDlg, IDC_LIST);
  100. RECT rc;
  101. GetClientRect(hwnd, &rc);
  102. LVCOLUMN lvc;
  103. lvc.mask = LVCF_SUBITEM | LVCF_WIDTH;
  104. lvc.iSubItem = 0;
  105. lvc.cx = rc.right - GetSystemMetrics(SM_CXVSCROLL);
  106. ListView_InsertColumn( hwnd, 0, &lvc );
  107. PopulatePrefixList(hwnd);
  108. if (ListView_GetItemCount(hwnd) > 0)
  109. {
  110. m_iSelectedItem = 0;
  111. ListView_SetItemState(hwnd, 0, LVIS_FOCUSED|LVIS_SELECTED, LVIS_FOCUSED|LVIS_SELECTED);
  112. }
  113. SetPrefixControlsState(hwndDlg, bAll);
  114. hwnd = GetDlgItem(hwndDlg,IDC_DIALNUMBER);
  115. SHUnicodeToTChar(m_pRule->GetNumberToDial(), szText, ARRAYSIZE(szText));
  116. SetWindowText(hwnd, szText);
  117. SendMessage(hwnd, EM_SETLIMITTEXT, CPL_SETTEXTLIMIT, 0);
  118. if ( m_pRule->HasDialNumber() )
  119. {
  120. SendMessage( GetDlgItem(hwndDlg,IDC_DIALCHECK), BM_SETCHECK, BST_CHECKED, 0 );
  121. }
  122. else
  123. {
  124. EnableWindow(hwnd, FALSE);
  125. }
  126. LimitInput(hwnd, LIF_ALLOWNUMBER|LIF_ALLOWPOUND|LIF_ALLOWSTAR|LIF_ALLOWSPACE|LIF_ALLOWCOMMA);
  127. if ( m_pRule->HasDialAreaCode() )
  128. {
  129. SendMessage( GetDlgItem(hwndDlg,IDC_DIALAREACODE), BM_SETCHECK, BST_CHECKED, 0 );
  130. }
  131. return 1;
  132. }
  133. BOOL CAreaCodeRuleDialog::OnCommand(HWND hwndParent, int wID, int wNotifyCode, HWND hwndCrl)
  134. {
  135. switch (wID)
  136. {
  137. case IDOK:
  138. if (!ApplyChanges(hwndParent) )
  139. {
  140. break;
  141. }
  142. // fall through
  143. case IDCANCEL:
  144. HideToolTip();
  145. EndDialog(hwndParent,wID);
  146. break;
  147. case IDC_ALLPREFIXES:
  148. case IDC_LISTEDPREFIXES:
  149. SetPrefixControlsState(hwndParent, IDC_ALLPREFIXES==wID);
  150. break;
  151. case IDC_ADD:
  152. AddPrefix(hwndParent);
  153. break;
  154. case IDC_REMOVE:
  155. RemoveSelectedPrefix(hwndParent);
  156. break;
  157. case IDC_DIALCHECK:
  158. if ( BN_CLICKED == wNotifyCode )
  159. {
  160. BOOL bOn = SendMessage(hwndCrl, BM_GETCHECK, 0,0) == BST_CHECKED;
  161. HWND hwnd = GetDlgItem(hwndParent, IDC_DIALNUMBER);
  162. EnableWindow(hwnd, bOn);
  163. if ( bOn )
  164. {
  165. SetFocus(hwnd);
  166. }
  167. }
  168. break;
  169. default:
  170. return 0;
  171. }
  172. return 1;
  173. }
  174. BOOL CAreaCodeRuleDialog::OnNotify(HWND hwndDlg, LPNMHDR pnmhdr)
  175. {
  176. switch (pnmhdr->idFrom)
  177. {
  178. case IDC_LIST:
  179. #define pnmlv ((LPNMLISTVIEW)pnmhdr)
  180. switch (pnmhdr->code)
  181. {
  182. case LVN_ITEMCHANGED:
  183. if ( (pnmlv->uChanged & LVIF_STATE) && (pnmlv->uNewState & LVIS_SELECTED) )
  184. {
  185. m_iSelectedItem = pnmlv->iItem;
  186. EnableWindow(GetDlgItem(hwndDlg,IDC_REMOVE), pnmlv->iItem != -1);
  187. }
  188. break;
  189. case NM_DBLCLK:
  190. if ( -1 == pnmlv->iItem )
  191. {
  192. // Do new case
  193. AddPrefix(hwndDlg);
  194. }
  195. break;
  196. case NM_CLICK:
  197. if ( (-1 == pnmlv->iItem) && (-1!=m_iSelectedItem) )
  198. {
  199. m_iSelectedItem = -1;
  200. EnableWindow(GetDlgItem(hwndDlg,IDC_REMOVE), FALSE);
  201. }
  202. break;
  203. default:
  204. break;
  205. }
  206. break;
  207. #undef pnmlv
  208. default:
  209. return 0;
  210. }
  211. return 1;
  212. }
  213. BOOL CAreaCodeRuleDialog::ApplyChanges(HWND hwndParent)
  214. {
  215. TCHAR szAreaCode[MAX_INPUT] = {0};
  216. TCHAR szBuffer[MAX_INPUT];
  217. WCHAR wszBuffer[1024];
  218. PWSTR pwsz;
  219. HWND hwnd;
  220. // read the area code
  221. hwnd = GetDlgItem(hwndParent,IDC_AREACODE);
  222. GetWindowText(hwnd, szAreaCode, ARRAYSIZE(szAreaCode));
  223. if ( !*szAreaCode )
  224. {
  225. ShowErrorMessage(hwnd, IDS_NEEDANAREACODE);
  226. return FALSE;
  227. }
  228. // read the prefix list
  229. hwnd = GetDlgItem(hwndParent, IDC_LIST);
  230. int iItems = ListView_GetItemCount(hwnd);
  231. int i;
  232. LVITEM lvi;
  233. lvi.mask = LVIF_TEXT;
  234. lvi.iSubItem = 0;
  235. lvi.pszText = szBuffer;
  236. lvi.cchTextMax = ARRAYSIZE(szBuffer);
  237. UINT cchFree = ARRAYSIZE(wszBuffer);
  238. wszBuffer[1] = TEXT('\0'); // ensure double NULL termination if iItems is zero
  239. pwsz = wszBuffer;
  240. for (i=0; i<iItems; i++)
  241. {
  242. UINT cchPrefix;
  243. lvi.mask = LVIF_TEXT;
  244. lvi.iItem = i;
  245. ListView_GetItem(hwnd, &lvi);
  246. cchPrefix = lstrlen(szBuffer);
  247. if (cchPrefix >= cchFree)
  248. {
  249. // out of space in temp buffer. Hopefully this will never happen
  250. LOG((TL_ERROR, "ApplyChanges: Out of space in temp buffer."));
  251. break;
  252. }
  253. SHTCharToUnicode(szBuffer, pwsz, cchFree-1);
  254. pwsz += cchPrefix+1;
  255. cchFree -= cchPrefix+1;
  256. }
  257. *pwsz = NULL;
  258. BOOL bAllPrefixes;
  259. bAllPrefixes = SendMessage( GetDlgItem(hwndParent, IDC_ALLPREFIXES), BM_GETCHECK, 0,0 ) == BST_CHECKED;
  260. if ( !bAllPrefixes && iItems==0 )
  261. {
  262. ShowErrorMessage(GetDlgItem(hwndParent,IDC_ADD), IDS_NEEDPREFIXLIST);
  263. return FALSE;
  264. }
  265. BOOL dDialNumber;
  266. dDialNumber = SendMessage( GetDlgItem(hwndParent, IDC_DIALCHECK), BM_GETCHECK, 0,0 ) == BST_CHECKED;
  267. GetWindowText(GetDlgItem(hwndParent,IDC_DIALNUMBER), szBuffer, ARRAYSIZE(szBuffer));
  268. if ( dDialNumber && IsEmptyOrHasOnlySpaces(szBuffer))
  269. {
  270. ShowErrorMessage(GetDlgItem(hwndParent,IDC_DIALNUMBER), IDS_NEEDDIALNUMBER);
  271. return FALSE;
  272. }
  273. // TODO:
  274. // for each prefix, look for a conflicting rule.
  275. // if a conflict is found, alert the user.
  276. // based on the alert optionally ammend the conflicting rule
  277. // now we have verified the input is valid, go ahead and update everything:
  278. // save the prefix list even if Applies To All is selected.
  279. m_pRule->SetPrefixList( wszBuffer, (ARRAYSIZE(wszBuffer)-cchFree+1)*sizeof(WCHAR) );
  280. // read all verse select prefixes radio button
  281. m_pRule->SetAppliesToAllPrefixes( bAllPrefixes );
  282. // Save the area code.
  283. SHTCharToUnicode(szAreaCode, wszBuffer, ARRAYSIZE(wszBuffer));
  284. m_pRule->SetAreaCode( wszBuffer );
  285. // Save the dial number
  286. SHTCharToUnicode(szBuffer, wszBuffer, ARRAYSIZE(wszBuffer));
  287. m_pRule->SetNumberToDial( wszBuffer );
  288. // Save the dial number checkbox
  289. m_pRule->SetDialNumber( dDialNumber );
  290. // read the dial area code check box
  291. BOOL b;
  292. b = SendMessage( GetDlgItem(hwndParent, IDC_DIALAREACODE), BM_GETCHECK, 0,0 ) == BST_CHECKED;
  293. m_pRule->SetDialAreaCode( b );
  294. return TRUE;
  295. }
  296. void CAreaCodeRuleDialog::AddPrefix(HWND hwndParent)
  297. {
  298. CEditDialog ed;
  299. INT_PTR iRes = ed.DoModal(hwndParent, IDS_ADDPREFIX, IDS_TYPEPREFIX, IDS_ACPREFIXES, LIF_ALLOWNUMBER|LIF_ALLOWSPACE|LIF_ALLOWCOMMA);
  300. if ( iRes == (INT_PTR)IDOK )
  301. {
  302. LPTSTR psz = ed.GetString();
  303. if (!psz)
  304. return; // should be impossible, but better safe than sorry
  305. // The string can contain multiple prefixes seperated by spaces, parse it
  306. // up and add one prefix for each chunk
  307. while (*psz)
  308. {
  309. LPTSTR pszNext;
  310. TCHAR ch;
  311. HWND hwndList = GetDlgItem(hwndParent, IDC_LIST);
  312. // trim leading spaces
  313. while ((*psz == TEXT(' ')) || (*psz == TEXT(',')))
  314. psz++;
  315. // check if trimming the spaces toke us to the end of the string
  316. if ( *psz )
  317. {
  318. // find next space and make it a temporary null
  319. pszNext = psz;
  320. while (*pszNext && (*pszNext != TEXT(' ')) && (*pszNext != TEXT(',')) )
  321. pszNext++;
  322. ch = *pszNext;
  323. *pszNext = NULL;
  324. // add this item to the list
  325. LVITEM lvi;
  326. lvi.mask = LVIF_TEXT;
  327. lvi.pszText = psz;
  328. lvi.iItem = 0;
  329. lvi.iSubItem = 0;
  330. ListView_InsertItem(hwndList, &lvi);
  331. // replace our tempory null with it's previous value
  332. *pszNext = ch;
  333. // advance the psz point
  334. psz = pszNext;
  335. }
  336. }
  337. }
  338. }
  339. void CAreaCodeRuleDialog::RemoveSelectedPrefix(HWND hwndParent)
  340. {
  341. if ( -1 != m_iSelectedItem )
  342. {
  343. m_iSelectedItem = DeleteItemAndSelectPrevious(hwndParent, IDC_LIST, m_iSelectedItem, IDC_REMOVE, IDC_ADD);
  344. }
  345. }
  346. int DeleteItemAndSelectPrevious( HWND hwndParent, int iList, int iItem, int iDel, int iAdd )
  347. {
  348. HWND hwnd = GetDlgItem(hwndParent, iList);
  349. ListView_DeleteItem(hwnd, iItem);
  350. // Try to select the previous item, if possible
  351. iItem--;
  352. if ( 0 > iItem )
  353. {
  354. iItem = 0;
  355. }
  356. LVITEM lvi;
  357. lvi.mask = LVIF_PARAM;
  358. lvi.iItem = iItem;
  359. lvi.iSubItem = 0;
  360. if ( ListView_GetItem(hwnd, &lvi) )
  361. {
  362. ListView_SetItemState(hwnd, iItem, LVIS_FOCUSED|LVIS_SELECTED, LVIS_FOCUSED|LVIS_SELECTED);
  363. ListView_EnsureVisible(hwnd, iItem, FALSE);
  364. }
  365. else
  366. {
  367. iItem = -1;
  368. }
  369. hwnd = GetDlgItem(hwndParent,iDel);
  370. if ( -1 == iItem )
  371. {
  372. if ( GetFocus() == hwnd )
  373. {
  374. HWND hwndDef = GetDlgItem(hwndParent,iAdd);
  375. SendMessage(hwnd, BM_SETSTYLE, BS_PUSHBUTTON, MAKELPARAM(TRUE,0));
  376. SendMessage(hwndDef, BM_SETSTYLE, BS_DEFPUSHBUTTON, MAKELPARAM(TRUE,0));
  377. SetFocus(hwndDef);
  378. }
  379. }
  380. EnableWindow(hwnd, -1!=iItem);
  381. return iItem;
  382. }
  383. BOOL IsEmptyOrHasOnlySpaces(PTSTR pwszStr)
  384. {
  385. while(*pwszStr)
  386. if(*pwszStr++ != TEXT(' '))
  387. return FALSE;
  388. return TRUE;
  389. }