Source code of Windows XP (NT5)
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.

483 lines
14 KiB

  1. /****************************************************************************
  2. Copyright (c) 1998-1999 Microsoft Corporation
  3. Module Name: cplareacodetab.cpp
  4. Author: toddb - 10/06/98
  5. ****************************************************************************/
  6. //
  7. // Functions used only by the Area Code Rules tab of the New Location Property Sheet.
  8. // Shared functions are in the Location.cpp file.
  9. //
  10. #include "cplPreComp.h"
  11. #include "cplLocationPS.h"
  12. INT_PTR CALLBACK CLocationPropSheet::AreaCode_DialogProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
  13. {
  14. CLocationPropSheet* pthis = (CLocationPropSheet*) GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
  15. switch(uMsg)
  16. {
  17. case WM_INITDIALOG:
  18. pthis = (CLocationPropSheet*)(((PROPSHEETPAGE*)lParam)->lParam);
  19. SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) pthis);
  20. return pthis->AreaCode_OnInitDialog(hwndDlg);
  21. case WM_COMMAND:
  22. return pthis->AreaCode_OnCommand(hwndDlg, LOWORD(wParam), HIWORD(wParam), (HWND)lParam );
  23. case WM_NOTIFY:
  24. return pthis->AreaCode_OnNotify(hwndDlg, (LPNMHDR)lParam);
  25. case WM_HELP:
  26. // Process clicks on controls after Context Help mode selected
  27. WinHelp ((HWND)((LPHELPINFO)lParam)->hItemHandle, gszHelpFile, HELP_WM_HELP, (DWORD_PTR)(LPTSTR) a103HelpIDs);
  28. break;
  29. case WM_CONTEXTMENU:
  30. // Process right-clicks on controls
  31. WinHelp ((HWND) wParam, gszHelpFile, HELP_CONTEXTMENU, (DWORD_PTR)(LPVOID) a103HelpIDs);
  32. break;
  33. }
  34. return 0;
  35. }
  36. void BuildRuleDescription(CAreaCodeRule * pRule, LPTSTR szText, UINT cchSize)
  37. {
  38. TCHAR szAreaCode[MAX_INPUT];
  39. TCHAR szNumToDial[MAX_INPUT];
  40. BOOL hHasDialAreaCode = pRule->HasDialAreaCode();
  41. BOOL bHasDialNumber = pRule->HasDialNumber();
  42. // we almost always need these strings so go ahead and convert them
  43. SHUnicodeToTChar( pRule->GetAreaCode(), szAreaCode, ARRAYSIZE(szAreaCode));
  44. SHUnicodeToTChar( pRule->GetNumberToDial(), szNumToDial, ARRAYSIZE(szNumToDial));
  45. // Just a little sanity check so we don't get crappy looking strings.
  46. if ( bHasDialNumber && !*szNumToDial )
  47. {
  48. bHasDialNumber = FALSE;
  49. }
  50. int iFormatString;
  51. // TODO: Special default rules processing
  52. // if ( pRule == special rule that always shows up last )
  53. // {
  54. // iFormatString = IDS_DAIL_ONEpAC_ALLOTHER;
  55. // }
  56. // else
  57. if ( pRule->HasAppliesToAllPrefixes() )
  58. {
  59. if ( bHasDialNumber )
  60. {
  61. if ( hHasDialAreaCode )
  62. {
  63. // Dial '%2' plus the area code before the number for all numbers within the %1 area code.
  64. iFormatString = IDS_DIAL_XpAC_FORALL;
  65. }
  66. else
  67. {
  68. // Dial '%2' before the number for all numbers within the %1 area code.
  69. iFormatString = IDS_DIAL_X_FORALL;
  70. }
  71. }
  72. else if ( hHasDialAreaCode )
  73. {
  74. // Dial the area code before the number for all numbers within the %1 area code.
  75. iFormatString = IDS_DIAL_AC_FORALL;
  76. }
  77. else
  78. {
  79. // Dial only the number for all numbers within the %1 area code.
  80. iFormatString = IDS_DIAL_NUMONLY_FORALL;
  81. }
  82. }
  83. else
  84. {
  85. if ( bHasDialNumber )
  86. {
  87. if ( hHasDialAreaCode )
  88. {
  89. // Dial '%2' plus the area code before the number for numbers with the selected prefixes within the %1 area code.
  90. iFormatString = IDS_DIAL_XpAC_FORSELECTED;
  91. }
  92. else
  93. {
  94. // Dial '%2' before the number for numbers with the selected prefixes within the %1 area code.
  95. iFormatString = IDS_DIAL_X_FORSELECTED;
  96. }
  97. }
  98. else if ( hHasDialAreaCode )
  99. {
  100. // Dial the area code before the number for numbers with the selected prefixes within the %1 area code.
  101. iFormatString = IDS_DIAL_AC_FORSELECTED;
  102. }
  103. else
  104. {
  105. // Dial only the number for numbers with the selected prefixes within the %1 area code.
  106. iFormatString = IDS_DIAL_NUMONLY_FORSELECTED;
  107. }
  108. }
  109. TCHAR szFormatString[512];
  110. LPTSTR aArgs[] = {szAreaCode,szNumToDial};
  111. LoadString( GetUIInstance(), iFormatString, szFormatString, ARRAYSIZE(szFormatString) );
  112. FormatMessage(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ARGUMENT_ARRAY,
  113. szFormatString, 0,0, szText, cchSize, (va_list *)aArgs );
  114. }
  115. void BuildRuleText(CAreaCodeRule * pRule, LPTSTR szText, UINT cchSize)
  116. {
  117. TCHAR szNumToDial[MAX_INPUT];
  118. SHUnicodeToTChar( pRule->GetNumberToDial(), szNumToDial, ARRAYSIZE(szNumToDial));
  119. // Just a little sanity check so we don't get crappy looking strings.
  120. BOOL bHasDialNumber = pRule->HasDialNumber();
  121. if ( bHasDialNumber && !*szNumToDial )
  122. {
  123. bHasDialNumber = FALSE;
  124. }
  125. if ( bHasDialNumber )
  126. {
  127. int iFormatString;
  128. TCHAR szFormatString[512];
  129. LPTSTR aArgs[] = {szNumToDial};
  130. if ( pRule->HasDialAreaCode() )
  131. {
  132. // both string
  133. iFormatString = IDS_DIALXPLUSAREACODE;
  134. }
  135. else
  136. {
  137. // dial number string
  138. iFormatString = IDS_DIALX;
  139. }
  140. LoadString( GetUIInstance(), iFormatString, szFormatString, ARRAYSIZE(szFormatString) );
  141. FormatMessage(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ARGUMENT_ARRAY,
  142. szFormatString, 0,0, szText, cchSize, (va_list *)aArgs );
  143. }
  144. else if ( pRule->HasDialAreaCode() )
  145. {
  146. // area code only string
  147. LoadString( GetUIInstance(), IDS_DIALAREACODE, szText, cchSize );
  148. }
  149. else
  150. {
  151. // none of the above string
  152. LoadString( GetUIInstance(), IDS_DIALNUMBERONLY, szText, cchSize );
  153. }
  154. }
  155. BOOL CLocationPropSheet::AreaCode_OnInitDialog(HWND hDlg)
  156. {
  157. // add the three columns to the listview
  158. RECT rc;
  159. TCHAR szText[MAX_INPUT];
  160. HWND hwndList = GetDlgItem(hDlg, IDC_LIST);
  161. GetClientRect(hwndList, &rc);
  162. int cxList = rc.right - GetSystemMetrics(SM_CXVSCROLL);
  163. LVCOLUMN lvc;
  164. lvc.mask = LVCF_TEXT | LVCF_SUBITEM | LVCF_WIDTH;
  165. lvc.pszText = szText;
  166. struct {
  167. int iStrID;
  168. int cxPercent;
  169. } aData[] = {
  170. { IDS_AREACODE, 20 },
  171. { IDS_PREFIXES, 20 },
  172. { IDS_RULE, 60 },
  173. };
  174. for (int i=0; i<ARRAYSIZE(aData); i++)
  175. {
  176. LoadString(GetUIInstance(), aData[i].iStrID, szText, ARRAYSIZE(szText));
  177. lvc.iSubItem = i;
  178. lvc.cx = MulDiv(cxList, aData[i].cxPercent, 100);
  179. ListView_InsertColumn( hwndList, i, &lvc );
  180. }
  181. ListView_SetExtendedListViewStyleEx(hwndList,
  182. LVS_EX_LABELTIP | LVS_EX_FULLROWSELECT,
  183. LVS_EX_LABELTIP | LVS_EX_FULLROWSELECT);
  184. PopulateAreaCodeRuleList( hwndList );
  185. SetDataForSelectedRule(hDlg);
  186. return 1;
  187. }
  188. void CLocationPropSheet::SetDataForSelectedRule(HWND hDlg)
  189. {
  190. TCHAR szText[512];
  191. // Set the button states
  192. EnableWindow(GetDlgItem(hDlg, IDC_EDIT), 0!=m_pRule);
  193. EnableWindow(GetDlgItem(hDlg, IDC_DELETE), 0!=m_pRule);
  194. if ( m_pRule )
  195. {
  196. // Set the description text
  197. BuildRuleDescription(m_pRule, szText, ARRAYSIZE(szText));
  198. }
  199. else
  200. {
  201. // text for when no rule is selected:
  202. LoadString(GetUIInstance(), IDS_SELECTARULE, szText, ARRAYSIZE(szText));
  203. }
  204. SetWindowText(GetDlgItem(hDlg, IDC_DESCRIPTIONTEXT), szText);
  205. }
  206. void CLocationPropSheet::AddRuleToList( HWND hwndList, CAreaCodeRule * pRule, BOOL bSelect )
  207. {
  208. TCHAR szText[512];
  209. LVITEM lvi;
  210. SHUnicodeToTChar( pRule->GetAreaCode(), szText, ARRAYSIZE(szText));
  211. lvi.pszText = szText;
  212. lvi.mask = LVIF_TEXT | LVIF_PARAM;
  213. lvi.iItem = 0;
  214. lvi.iSubItem = 0;
  215. lvi.stateMask = LVIS_STATEIMAGEMASK;
  216. lvi.lParam = (LPARAM)pRule;
  217. if ( bSelect )
  218. {
  219. lvi.mask |= LVIF_STATE;
  220. lvi.state = LVIS_SELECTED | LVIS_FOCUSED;
  221. // We added the new rule in the selected state so update m_pRule
  222. m_pRule = pRule;
  223. // Since we now have a selected rule, update the button states
  224. HWND hwndParent = GetParent(hwndList);
  225. EnableWindow( GetDlgItem(hwndParent, IDC_EDIT), TRUE );
  226. EnableWindow( GetDlgItem(hwndParent, IDC_DELETE), TRUE );
  227. }
  228. int iItem = ListView_InsertItem(hwndList, &lvi);
  229. LoadString(GetUIInstance(), pRule->HasAppliesToAllPrefixes()?IDS_ALLPREFIXES:IDS_SELECTEDPREFIXES,
  230. szText, ARRAYSIZE(szText));
  231. ListView_SetItemText(hwndList, iItem, 1, szText);
  232. BuildRuleText( pRule, szText, ARRAYSIZE(szText));
  233. ListView_SetItemText(hwndList, iItem, 2, szText);
  234. }
  235. void CLocationPropSheet::RemoveRuleFromList(HWND hwndList, BOOL bSelect)
  236. {
  237. LVFINDINFO lvfi;
  238. lvfi.flags = LVFI_PARAM;
  239. lvfi.lParam = (LPARAM)m_pRule;
  240. int iItem = ListView_FindItem(hwndList,-1,&lvfi);
  241. if ( -1 != iItem )
  242. {
  243. if ( bSelect )
  244. {
  245. iItem = DeleteItemAndSelectPrevious( GetParent(hwndList), IDC_LIST, iItem, IDC_DELETE, IDC_NEW );
  246. if ( -1 != iItem )
  247. {
  248. LVITEM lvi;
  249. lvi.iItem = iItem;
  250. lvi.iSubItem = 0;
  251. lvi.mask = LVIF_PARAM;
  252. ListView_GetItem( hwndList, &lvi );
  253. // Store the currently selected item
  254. m_pRule = (CAreaCodeRule *)lvi.lParam;
  255. }
  256. else
  257. {
  258. m_pRule = NULL;
  259. }
  260. }
  261. else
  262. {
  263. ListView_DeleteItem(hwndList,iItem);
  264. m_pRule = NULL;
  265. }
  266. }
  267. }
  268. void CLocationPropSheet::PopulateAreaCodeRuleList( HWND hwndList )
  269. {
  270. m_pLoc->ResetRules();
  271. int i;
  272. int iItems;
  273. CAreaCodeRule * pRule;
  274. iItems = m_pLoc->GetNumRules();
  275. for (i=0; i<iItems; i++)
  276. {
  277. if ( S_OK == m_pLoc->NextRule(1,&pRule,NULL) )
  278. {
  279. AddRuleToList( hwndList, pRule, FALSE );
  280. }
  281. }
  282. }
  283. BOOL CLocationPropSheet::AreaCode_OnCommand(HWND hwndParent, int wID, int wNotifyCode, HWND hwndCrl)
  284. {
  285. switch ( wID )
  286. {
  287. case IDC_NEW:
  288. case IDC_EDIT:
  289. LaunchNewRuleDialog(IDC_NEW == wID,hwndParent);
  290. break;
  291. case IDC_DELETE:
  292. DeleteSelectedRule(GetDlgItem(hwndParent,IDC_LIST));
  293. break;
  294. default:
  295. return 0;
  296. }
  297. return 1;
  298. }
  299. void CLocationPropSheet::LaunchNewRuleDialog(BOOL bNew, HWND hwndParent)
  300. {
  301. CAreaCodeRule * pRule;
  302. if ( bNew )
  303. {
  304. // Initialize with default values
  305. pRule = new CAreaCodeRule;
  306. if ( !pRule )
  307. {
  308. return;
  309. }
  310. pRule->Initialize(L"",L"1",RULE_APPLIESTOALLPREFIXES,NULL,0);
  311. }
  312. else if ( m_pRule )
  313. {
  314. // Initialize with m_pRule's values
  315. pRule = m_pRule;
  316. }
  317. else
  318. {
  319. // This should be impossible
  320. return;
  321. }
  322. CAreaCodeRuleDialog acrd( bNew, pRule );
  323. if ( IDOK == acrd.DoModal(hwndParent) )
  324. {
  325. // The user changed something
  326. HWND hwndList = GetDlgItem(hwndParent,IDC_LIST);
  327. SendMessage(GetParent(hwndParent), PSM_CHANGED, (WPARAM)hwndParent, 0);
  328. if ( bNew )
  329. {
  330. m_pLoc->AddRule(pRule);
  331. }
  332. else
  333. {
  334. // Assert( m_pRule == pRule );
  335. RemoveRuleFromList(hwndList, FALSE);
  336. }
  337. AddRuleToList(hwndList, pRule, TRUE);
  338. SetDataForSelectedRule(hwndParent);
  339. }
  340. else if ( bNew )
  341. {
  342. delete pRule;
  343. }
  344. }
  345. void CLocationPropSheet::DeleteSelectedRule(HWND hwndList)
  346. {
  347. // First we confirm the delete with the user
  348. TCHAR szText[1024];
  349. TCHAR szTitle[128];
  350. int result;
  351. HWND hwndParent = GetParent(hwndList);
  352. LoadString(GetUIInstance(), IDS_DELETERULETEXT, szText, ARRAYSIZE(szText));
  353. LoadString(GetUIInstance(), IDS_CONFIRMDELETE, szTitle, ARRAYSIZE(szTitle));
  354. result = SHMessageBoxCheck( hwndParent, szText, szTitle, MB_YESNO, IDYES, TEXT("TAPIDeleteAreaCodeRule") );
  355. if ( IDYES == result )
  356. {
  357. // remove the item corresponding to m_pRule from the list
  358. m_pLoc->RemoveRule(m_pRule);
  359. RemoveRuleFromList(hwndList, TRUE);
  360. // Now we want to select the next rule in the list
  361. HWND hwndParent = GetParent(hwndList);
  362. SetDataForSelectedRule(hwndParent);
  363. SendMessage(GetParent(hwndParent), PSM_CHANGED, (WPARAM)hwndParent, 0);
  364. }
  365. }
  366. BOOL CLocationPropSheet::AreaCode_OnNotify(HWND hwndDlg, LPNMHDR pnmhdr)
  367. {
  368. // Let the generic handler have a crack at it first
  369. OnNotify(hwndDlg, pnmhdr);
  370. if (pnmhdr->idFrom == IDC_LIST)
  371. {
  372. #define pnmlv ((LPNMLISTVIEW)pnmhdr)
  373. switch (pnmhdr->code)
  374. {
  375. case LVN_ITEMCHANGED:
  376. if ( pnmlv->uChanged & LVIF_STATE )
  377. {
  378. if (pnmlv->uNewState & LVIS_SELECTED)
  379. {
  380. LVITEM lvi;
  381. lvi.iItem = pnmlv->iItem;
  382. lvi.iSubItem = pnmlv->iSubItem;
  383. lvi.mask = LVIF_PARAM;
  384. ListView_GetItem( pnmhdr->hwndFrom, &lvi );
  385. // Store the currently selected item
  386. m_pRule = (CAreaCodeRule *)lvi.lParam;
  387. }
  388. else
  389. {
  390. m_pRule = NULL;
  391. }
  392. SetDataForSelectedRule(hwndDlg);
  393. }
  394. break;
  395. case NM_DBLCLK:
  396. if ( (-1 == pnmlv->iItem) || !m_pRule )
  397. {
  398. // Do new case
  399. LaunchNewRuleDialog(TRUE,hwndDlg);
  400. }
  401. else
  402. {
  403. // Do Edit case
  404. LaunchNewRuleDialog(FALSE,hwndDlg);
  405. }
  406. break;
  407. default:
  408. break;
  409. }
  410. #undef pnmlv
  411. }
  412. return 1;
  413. }