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.

571 lines
17 KiB

  1. /****************************************************************************\
  2. *
  3. * FILEDLG.CPP - Code to manage the Rating Systems dialog.
  4. *
  5. * gregj 06/27/96 Moved code here from msludlg.cpp and largely rewrote.
  6. *
  7. \****************************************************************************/
  8. /*INCLUDES--------------------------------------------------------------------*/
  9. #include "msrating.h"
  10. #include "ratings.h"
  11. #include "mslubase.h"
  12. #include "commctrl.h"
  13. #include "commdlg.h"
  14. #include "buffer.h"
  15. #include "filedlg.h" // CProviderDialog
  16. // #include "custfile.h" // CCustomFileDialog
  17. #include "debug.h"
  18. #include <shellapi.h>
  19. #include <contxids.h>
  20. #include <mluisupp.h>
  21. typedef BOOL (APIENTRY *PFNGETOPENFILENAME)(LPOPENFILENAME);
  22. DWORD CProviderDialog::aIds[] = {
  23. IDC_STATIC1, IDH_RATINGS_SYSTEM_RATSYS_LIST,
  24. IDC_PROVIDERLIST, IDH_RATINGS_SYSTEM_RATSYS_LIST,
  25. IDC_OPENPROVIDER, IDH_RATINGS_SYSTEM_RATSYS_ADD,
  26. IDC_CLOSEPROVIDER, IDH_RATINGS_SYSTEM_RATSYS_REMOVE,
  27. IDC_STATIC2, IDH_IGNORE,
  28. 0,0
  29. };
  30. CProviderDialog::CProviderDialog( PicsRatingSystemInfo * p_pPRSI )
  31. {
  32. m_pPRSI = p_pPRSI;
  33. }
  34. BOOL CProviderDialog::OpenTemplateDlg( CHAR * szFilename,UINT cbFilename )
  35. {
  36. CHAR szFilter[MAXPATHLEN];
  37. CHAR szOpenInfTitle[MAXPATHLEN];
  38. CHAR szInitialDir[MAXPATHLEN];
  39. GetSystemDirectory(szInitialDir, sizeof(szInitialDir));
  40. strcpyf(szFilename,szNULL);
  41. MLLoadStringA(IDS_RAT_OPENFILE, szOpenInfTitle,sizeof(szOpenInfTitle));
  42. // have to load the openfile filter in 2 stages, because the string
  43. // contains a terminating character and MLLoadString won't load the
  44. // whole thing in one go
  45. memset(szFilter,0,sizeof(szFilter));
  46. MLLoadStringA(IDS_RAT_FILTER_DESC,szFilter,sizeof(szFilter) - 10); // save some room for the filespec
  47. MLLoadStringA(IDS_RAT_FILTER,szFilter+strlenf(szFilter)+1,sizeof(szFilter)-
  48. (strlenf(szFilter)+1));
  49. OPENFILENAME ofn;
  50. memset(&ofn,0,sizeof(ofn));
  51. ofn.lStructSize = sizeof(ofn);
  52. ofn.hwndOwner = m_hWnd;
  53. ofn.hInstance = NULL;
  54. ofn.lpstrFilter = szFilter;
  55. ofn.lpstrFile = szFilename;
  56. ofn.nMaxFile = cbFilename;
  57. ofn.lpstrTitle = szOpenInfTitle;
  58. ofn.lpstrInitialDir = szInitialDir;
  59. ofn.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST
  60. | OFN_SHAREAWARE | OFN_HIDEREADONLY;
  61. BOOL fRet = ::GetOpenFileName( &ofn );
  62. #ifdef NEVER
  63. DWORD dwFlags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_NONETWORKBUTTON
  64. | OFN_SHAREAWARE | OFN_HIDEREADONLY;
  65. BOOL fRet = FALSE;
  66. CCustomFileDialog cfd( TRUE, // Local Files Only
  67. TRUE, // Open File
  68. NULL, // Default Extension
  69. NULL, // Initial Filename
  70. dwFlags, // Open File Flags
  71. szFilter, // Filter
  72. m_hWnd ); // Parent
  73. if ( cfd.DoModal( m_hWnd ) == IDOK )
  74. {
  75. fRet = TRUE;
  76. lstrcpy( szFilename, cfd.m_szFileName );
  77. }
  78. #endif
  79. return fRet;
  80. }
  81. void CProviderDialog::SetHorizontalExtent(HWND hwndLB, LPCSTR pszString)
  82. {
  83. HDC hDC = ::GetDC(hwndLB);
  84. HFONT hFont = (HFONT)::SendMessage(hwndLB, WM_GETFONT, 0, 0);
  85. HFONT hfontOld = (HFONT)::SelectObject(hDC, hFont);
  86. UINT cxSlop = ::GetSystemMetrics(SM_CXBORDER) * 4; /* 2 for LB border, 2 for margin inside border */
  87. UINT cxNewMaxExtent = 0;
  88. SIZE s;
  89. if (pszString != NULL) {
  90. ::GetTextExtentPoint(hDC, pszString, ::strlenf(pszString), &s);
  91. UINT cxCurExtent = (UINT)::SendMessage(hwndLB, LB_GETHORIZONTALEXTENT, 0, 0);
  92. if ((UINT)s.cx > cxCurExtent)
  93. cxNewMaxExtent = s.cx + cxSlop;
  94. }
  95. else {
  96. UINT cItems = (UINT)::SendMessage(hwndLB, LB_GETCOUNT, 0, 0);
  97. for (UINT i=0; i<cItems; i++) {
  98. char szItem[MAXPATHLEN]; /* we know we have pathnames in the list */
  99. ::SendMessage(hwndLB, LB_GETTEXT, i, (LPARAM)(LPSTR)szItem);
  100. ::GetTextExtentPoint(hDC, szItem, ::strlenf(szItem), &s);
  101. if ((UINT)s.cx > cxNewMaxExtent)
  102. cxNewMaxExtent = s.cx;
  103. }
  104. cxNewMaxExtent += cxSlop;
  105. }
  106. if (cxNewMaxExtent > 0)
  107. ::SendMessage(hwndLB, LB_SETHORIZONTALEXTENT, (WPARAM)cxNewMaxExtent, 0);
  108. ::SelectObject(hDC, hfontOld);
  109. ::ReleaseDC(hwndLB, hDC);
  110. }
  111. void CProviderDialog::AddProviderToList(UINT idx, LPCSTR pszFilename)
  112. {
  113. UINT_PTR iItem = SendDlgItemMessage(IDC_PROVIDERLIST, LB_ADDSTRING, 0,
  114. (LPARAM)pszFilename);
  115. if (iItem != LB_ERR)
  116. {
  117. SendDlgItemMessage(IDC_PROVIDERLIST, LB_SETITEMDATA, iItem, (LPARAM)idx);
  118. }
  119. }
  120. BOOL CProviderDialog::InitProviderDlg( void )
  121. {
  122. ASSERT( m_pPRSI );
  123. if ( ! m_pPRSI )
  124. {
  125. TraceMsg( TF_ERROR, "CProviderDialog::InitProviderDlg() - m_pPRSI is NULL!" );
  126. return FALSE;
  127. }
  128. for (UINT i = 0; i < (UINT)m_pPRSI->arrpPRS.Length(); ++i)
  129. {
  130. PicsRatingSystem *pPRS = m_pPRSI->arrpPRS[i];
  131. ProviderData pd;
  132. pd.pPRS = pPRS;
  133. pd.pprsNew = NULL;
  134. pd.nAction = PROVIDER_KEEP;
  135. if (!m_aPD.Append(pd))
  136. return FALSE;
  137. if(pPRS->etstrName.Get())
  138. {
  139. // add provider using name
  140. AddProviderToList(i, pPRS->etstrName.Get());
  141. }
  142. else if(pPRS->etstrFile.Get())
  143. {
  144. // no name - possibly missing file, use filespec instead
  145. AddProviderToList(i, pPRS->etstrFile.Get());
  146. }
  147. }
  148. SetHorizontalExtent(GetDlgItem(IDC_PROVIDERLIST), NULL);
  149. ::EnableWindow(GetDlgItem(IDC_CLOSEPROVIDER), FALSE);
  150. ::EnableWindow(GetDlgItem(IDC_OPENPROVIDER), TRUE);
  151. if (SendDlgItemMessage(IDC_PROVIDERLIST, LB_SETCURSEL, 0, 0) != LB_ERR)
  152. {
  153. ::EnableWindow(GetDlgItem(IDC_CLOSEPROVIDER), TRUE);
  154. }
  155. return TRUE;
  156. }
  157. void CProviderDialog::EndProviderDlg(BOOL fRet)
  158. {
  159. ASSERT( m_pPRSI );
  160. if ( ! m_pPRSI )
  161. {
  162. TraceMsg( TF_ERROR, "CProviderDialog::EndProviderDlg() - m_pPRSI is NULL!" );
  163. return;
  164. }
  165. /* Go through our auxiliary array and delete any provider structures which
  166. * we added in this dialog. Note that if the user previously hit OK, the
  167. * providers which were added will be marked as KEEP when they're put back
  168. * in the main data structure, so we won't delete them here.
  169. */
  170. UINT cProviders = m_aPD.Length();
  171. for (UINT i=0; i<cProviders; i++)
  172. {
  173. if (m_aPD[i].nAction == PROVIDER_ADD)
  174. {
  175. delete m_aPD[i].pPRS;
  176. m_aPD[i].pPRS = NULL;
  177. }
  178. if (m_aPD[i].pprsNew != NULL)
  179. {
  180. delete m_aPD[i].pprsNew;
  181. m_aPD[i].pprsNew = NULL;
  182. }
  183. }
  184. EndDialog(fRet);
  185. }
  186. void CProviderDialog::CommitProviderDlg( void )
  187. {
  188. ASSERT( m_pPRSI );
  189. if ( ! m_pPRSI )
  190. {
  191. TraceMsg( TF_ERROR, "CProviderDialog::CommitProviderDlg() - m_pPRSI is NULL!" );
  192. return;
  193. }
  194. /* We check twice to see if there are any rating systems installed.
  195. * Up front, we see if there's anything in the list, before we commit
  196. * any changes; this lets the user change their mind, cancel the dialog,
  197. * and not lose any settings.
  198. *
  199. * The second check is down at the end, seeing if there are any valid
  200. * rating systems left after we're done committing changes. Note that
  201. * the results of that check could be different than this first one if
  202. * any rating systems fail to load for some reason.
  203. *
  204. * If we prompt the user the first time and he says he really doesn't
  205. * want any rating systems (i.e., wants to disable ratings completely),
  206. * we don't bother prompting the second time since he's already said no.
  207. * Hence the fPrompted flag.
  208. */
  209. BOOL fPrompted = FALSE;
  210. if (SendDlgItemMessage(IDC_PROVIDERLIST, LB_GETCOUNT, 0, 0) == 0) {
  211. MyMessageBox(m_hWnd, IDS_NO_PROVIDERS, IDS_GENERIC, MB_OK);
  212. return;
  213. }
  214. /* Go through the list and add the new ones.
  215. * Note that this does NOT destruct the pPRS objects themselves, it just
  216. * empties the array. We have saved copies of all of them in our auxiliary
  217. * array.
  218. */
  219. m_pPRSI->arrpPRS.ClearAll();
  220. UINT cItems = m_aPD.Length();
  221. for (UINT i=0; i<cItems; i++) {
  222. switch (m_aPD[i].nAction) {
  223. case PROVIDER_DEL:
  224. DeleteUserSettings(m_aPD[i].pPRS);
  225. delete m_aPD[i].pPRS;
  226. m_aPD[i].pPRS = NULL;
  227. delete m_aPD[i].pprsNew;
  228. m_aPD[i].pprsNew = NULL;
  229. break;
  230. case PROVIDER_KEEP:
  231. if (m_aPD[i].pprsNew != NULL) {
  232. CheckUserSettings(m_aPD[i].pprsNew);
  233. m_pPRSI->arrpPRS.Append(m_aPD[i].pprsNew);
  234. delete m_aPD[i].pPRS;
  235. m_aPD[i].pPRS = NULL;
  236. m_aPD[i].pprsNew = NULL; /* protect from cleanup code */
  237. }
  238. else if (!(m_aPD[i].pPRS->dwFlags & PRS_ISVALID)) {
  239. delete m_aPD[i].pPRS;
  240. m_aPD[i].pPRS = NULL;
  241. }
  242. else {
  243. CheckUserSettings(m_aPD[i].pPRS);
  244. m_pPRSI->arrpPRS.Append(m_aPD[i].pPRS);
  245. }
  246. break;
  247. case PROVIDER_ADD:
  248. if (m_aPD[i].pPRS != NULL) {
  249. CheckUserSettings(m_aPD[i].pPRS);
  250. m_pPRSI->arrpPRS.Append(m_aPD[i].pPRS);
  251. m_aPD[i].nAction = PROVIDER_KEEP; /* keep this one now */
  252. }
  253. break;
  254. default:
  255. ASSERT(FALSE);
  256. }
  257. }
  258. if (m_pPRSI->arrpPRS.Length() == 0) {
  259. if (!fPrompted &&
  260. MyMessageBox(m_hWnd, IDS_NO_PROVIDERS, IDS_GENERIC, MB_YESNO) == IDYES)
  261. {
  262. return;
  263. }
  264. m_pPRSI->fRatingInstalled = FALSE;
  265. }
  266. else {
  267. m_pPRSI->fRatingInstalled = TRUE;
  268. }
  269. EndProviderDlg(TRUE);
  270. }
  271. void CProviderDialog::RemoveProvider( void )
  272. {
  273. ASSERT( m_pPRSI );
  274. if ( ! m_pPRSI )
  275. {
  276. TraceMsg( TF_ERROR, "CProviderDialog::AddProvider() - m_pPRSI is NULL!" );
  277. return;
  278. }
  279. UINT_PTR i = SendDlgItemMessage( IDC_PROVIDERLIST, LB_GETCURSEL,0,0);
  280. if (i != LB_ERR)
  281. {
  282. UINT idx = (UINT)SendDlgItemMessage( IDC_PROVIDERLIST,
  283. LB_GETITEMDATA, i, 0);
  284. if (idx < (UINT)m_aPD.Length()) {
  285. /* If the user added the provider in this dialog session, just
  286. * delete it from the array. The null pPRS pointer will be
  287. * detected later, so it's OK to leave the array element itself.
  288. * (Yes, if the user adds and removes an item over and over, we
  289. * consume 12 bytes of memory each time. Oh well.)
  290. *
  291. * If the item was there before the user launched the dialog,
  292. * then just mark it for deletion on OK.
  293. */
  294. if (m_aPD[idx].nAction == PROVIDER_ADD) {
  295. delete m_aPD[idx].pPRS;
  296. m_aPD[idx].pPRS = NULL;
  297. }
  298. else
  299. m_aPD[idx].nAction = PROVIDER_DEL;
  300. }
  301. SendDlgItemMessage(IDC_PROVIDERLIST, LB_DELETESTRING, i, 0);
  302. ::EnableWindow(GetDlgItem(IDC_CLOSEPROVIDER), FALSE);
  303. SendDlgItemMessage(IDC_PROVIDERLIST, LB_SETCURSEL,0,0);
  304. ::SetFocus(GetDlgItem(IDOK));
  305. SetHorizontalExtent(GetDlgItem(IDC_PROVIDERLIST), NULL);
  306. }
  307. }
  308. /* Returns zero if the two PicsRatingSystems have the same RAT-filename,
  309. * non-zero otherwise. Handles the '*' marker on the end for failed
  310. * loads. It is assumed that only pprsOld may have that marker.
  311. */
  312. int CProviderDialog::CompareProviderNames(PicsRatingSystem *pprsOld, PicsRatingSystem *pprsNew)
  313. {
  314. if (!pprsOld->etstrFile.fIsInit())
  315. return 1;
  316. UINT cbNewName = ::strlenf(pprsNew->etstrFile.Get());
  317. LPSTR pszOld = pprsOld->etstrFile.Get();
  318. int nCmp = ::strnicmpf(pprsNew->etstrFile.Get(), pszOld, cbNewName);
  319. if (nCmp != 0)
  320. return nCmp;
  321. pszOld += cbNewName;
  322. if (*pszOld == '\0' || (*pszOld == '*' && *(pszOld+1) == '\0'))
  323. return 0;
  324. return 1;
  325. }
  326. void CProviderDialog::AddProvider( PSTR szAddFileName )
  327. {
  328. BOOL fAdd=FALSE;
  329. char szFileName[MAXPATHLEN+1];
  330. ASSERT( m_pPRSI );
  331. if ( ! m_pPRSI )
  332. {
  333. TraceMsg( TF_ERROR, "CProviderDialog::AddProvider() - m_pPRSI is NULL!" );
  334. return;
  335. }
  336. if (szAddFileName!=NULL)
  337. {
  338. lstrcpy(szFileName,szAddFileName);
  339. fAdd=TRUE;
  340. }
  341. else
  342. {
  343. fAdd=OpenTemplateDlg(szFileName, sizeof(szFileName));
  344. }
  345. if (fAdd==TRUE)
  346. {
  347. PicsRatingSystem *pPRS;
  348. HRESULT hres = LoadRatingSystem(szFileName, &pPRS);
  349. if (FAILED(hres)) {
  350. if (pPRS != NULL) {
  351. pPRS->ReportError(hres);
  352. delete pPRS;
  353. pPRS = NULL;
  354. }
  355. }
  356. else {
  357. /* Check to see if this guy is already in the list. If he is,
  358. * the user might have said to delete him; in that case, put
  359. * him back. Otherwise, the system is already installed, so
  360. * tell the user he doesn't have to install it again.
  361. */
  362. for (UINT i=0; i<(UINT)m_aPD.Length(); i++) {
  363. ProviderData *ppd = &m_aPD[i];
  364. if (ppd->pPRS==NULL) {
  365. //This system was added and then removed during
  366. //this dialog session. It will be detected later,
  367. //so just skip it and keep appending entries.
  368. continue;
  369. }
  370. if (!CompareProviderNames(ppd->pPRS, pPRS)) {
  371. if (!(ppd->pPRS->dwFlags & PRS_ISVALID) &&
  372. (ppd->pprsNew == NULL))
  373. ppd->pprsNew = pPRS;
  374. else
  375. {
  376. delete pPRS; /* don't need copy */
  377. pPRS = NULL;
  378. }
  379. if (ppd->nAction == PROVIDER_DEL) {
  380. ppd->nAction = PROVIDER_KEEP;
  381. AddProviderToList(i, ppd->pPRS->etstrName.Get());
  382. }
  383. else {
  384. MyMessageBox(m_hWnd, IDS_ALREADY_INSTALLED, IDS_GENERIC, MB_OK);
  385. }
  386. return;
  387. }
  388. }
  389. /* This guy isn't already in the list. Add him to the listbox
  390. * and to the array.
  391. */
  392. ProviderData pd;
  393. pd.nAction = PROVIDER_ADD;
  394. pd.pPRS = pPRS;
  395. pd.pprsNew = NULL;
  396. if (!m_aPD.Append(pd)) {
  397. MyMessageBox(m_hWnd, IDS_LOADRAT_MEMORY, IDS_GENERIC, MB_OK | MB_ICONWARNING);
  398. delete pPRS;
  399. pPRS = NULL;
  400. return;
  401. }
  402. AddProviderToList(m_aPD.Length() - 1, pPRS->etstrName.Get());
  403. ::SetFocus(GetDlgItem(IDOK));
  404. SetHorizontalExtent(GetDlgItem(IDC_PROVIDERLIST), szFileName);
  405. }
  406. }
  407. }
  408. LRESULT CProviderDialog::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  409. {
  410. ASSERT( m_pPRSI );
  411. if ( ! m_pPRSI )
  412. {
  413. TraceMsg( TF_ERROR, "CProviderDialog::OnInitDialog() - m_pPRSI is NULL!" );
  414. return 0L;
  415. }
  416. if ( ! InitProviderDlg() )
  417. {
  418. MyMessageBox(m_hWnd, IDS_LOADRAT_MEMORY, IDS_GENERIC, MB_OK | MB_ICONSTOP);
  419. EndProviderDlg(FALSE);
  420. }
  421. if ( m_pPRSI->lpszFileName != NULL )
  422. {
  423. AddProvider( m_pPRSI->lpszFileName );
  424. }
  425. bHandled = FALSE;
  426. return 1L; // Let the system set the focus
  427. }
  428. LRESULT CProviderDialog::OnSelChange(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  429. {
  430. if (SendDlgItemMessage(IDC_PROVIDERLIST, LB_GETCURSEL, 0,0) >= 0)
  431. {
  432. ::EnableWindow(GetDlgItem(IDC_CLOSEPROVIDER), TRUE);
  433. bHandled = TRUE;
  434. }
  435. return 0L;
  436. }
  437. LRESULT CProviderDialog::OnOK(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  438. {
  439. CommitProviderDlg();
  440. return 0L;
  441. }
  442. LRESULT CProviderDialog::OnCancel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  443. {
  444. EndProviderDlg(FALSE);
  445. return 0L;
  446. }
  447. LRESULT CProviderDialog::OnCloseProvider(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  448. {
  449. RemoveProvider();
  450. return 0L;
  451. }
  452. LRESULT CProviderDialog::OnOpenProvider(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  453. {
  454. AddProvider();
  455. return 0L;
  456. }
  457. LRESULT CProviderDialog::OnHelp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  458. {
  459. SHWinHelpOnDemandWrap((HWND)((LPHELPINFO)lParam)->hItemHandle, ::szHelpFile,
  460. HELP_WM_HELP, (DWORD_PTR)(LPSTR)aIds);
  461. return 0L;
  462. }
  463. LRESULT CProviderDialog::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  464. {
  465. SHWinHelpOnDemandWrap((HWND)wParam, ::szHelpFile, HELP_CONTEXTMENU,
  466. (DWORD_PTR)(LPVOID)aIds);
  467. return 0L;
  468. }
  469. INT_PTR DoProviderDialog(HWND hDlg, PicsRatingSystemInfo *pPRSI)
  470. {
  471. CProviderDialog provDialog( pPRSI );
  472. return provDialog.DoModal( hDlg );
  473. }