home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / winfe / prefs.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  50.9 KB  |  1,965 lines

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18.  
  19. #include "stdafx.h"
  20. #ifndef _WIN32
  21. #include <ole2ui.h>
  22. #include <dispatch.h>
  23. #endif
  24. #include "prefs.h"
  25. #include <olectl.h>
  26. #include "winprefs/isppageo.h"
  27. #include "winprefs/brprefid.h"
  28. #ifdef MOZ_LOC_INDEP
  29. #include "winprefs/liprefid.h"
  30. #include "winprefs/iliprefs.h"
  31. #endif // MOZ_LOC_INDEP
  32. #ifdef EDITOR
  33. #include "winprefs/edprefid.h"
  34. #endif /* EDITOR */
  35. #ifdef MOZ_MAIL_NEWS
  36. #include "winprefs/mnprefid.h"
  37. #include "winprefs/mninterf.h"
  38. #endif /* MOZ_MAIL_NEWS */
  39. #include "winprefs/intlfont.h"
  40. #include "winprefs/ibrprefs.h"
  41. #include "winprefs/prefuiid.h"
  42. #include "winprefs/prefui.h"
  43. #include "cvffc.h"
  44. #ifdef EDITOR
  45. #include "edt.h"
  46. #endif // EDITOR
  47. #include "prefapi.h"
  48. #include "helper.h"
  49. #ifdef MOZ_MAIL_NEWS
  50. #include "mnprefs.h"
  51. #include "mailmisc.h"
  52. #include "wfemsg.h"
  53. #endif /* MOZ_MAIL_NEWS */
  54. #include "dlgseldg.h"
  55. #ifdef MOZ_MAIL_NEWS
  56. #include "addrbook.h"
  57. #include "addrfrm.h"    // for creating vcards
  58. #ifdef FEATURE_ADDRPROP
  59. #include "addrprop.h"
  60. #endif
  61. #endif /* MOZ_MAIL_NEWS */
  62.  
  63. extern "C" {
  64. #include "xpgetstr.h"
  65. #ifdef MOZ_MAIL_NEWS
  66. extern int MK_ADDR_BOOK_CARD;
  67. extern int MK_ADDR_NEW_CARD;
  68. extern int MK_MSG_SENT_L10N_NAME;  //Sent folder
  69. extern int MK_MSG_TEMPLATES_L10N_NAME;
  70. extern int MK_MSG_DRAFTS_L10N_NAME;
  71. extern int MK_MSG_REMOVE_HOST_CONFIRM;
  72. extern int MK_POP3_ONLY_ONE;
  73. extern int MK_MSG_REMOVE_MAILHOST_CONFIRM;
  74. #endif /* MOZ_MAIL_NEWS */
  75. };
  76. #include "nethelp.h"
  77. #include "ngdwtrst.h"
  78.  
  79. BOOL    g_bReloadAllWindows;
  80.  
  81. extern "C" void GetFolderServerNames
  82. (char* lpName, int nDefaultID, CString& folder, CString& server);
  83. extern "C" MSG_Host *DoAddNewsServer(CWnd* pParent, int nFromWhere);
  84.  
  85. /////////////////////////////////////////////////////////////////////////////
  86. // Helper functions
  87.  
  88. #ifndef _WIN32
  89. static LPVOID
  90. CoTaskMemAlloc(ULONG cb)
  91. {
  92.     LPMALLOC    pMalloc;
  93.     
  94.     if (SUCCEEDED(CoGetMalloc(MEMCTX_TASK, &pMalloc))) {
  95.         LPVOID    pv = pMalloc->Alloc(cb);
  96.  
  97.         pMalloc->Release();
  98.         return pv;
  99.     }
  100.  
  101.     return NULL;
  102. }
  103. #endif
  104.  
  105. // Convert an ANSI string to an OLE string (UNICODE string)
  106. static LPOLESTR NEAR
  107. AllocTaskOleString(LPCSTR lpszString)
  108. {
  109.     LPOLESTR    lpszResult;
  110.     UINT        nLen;
  111.  
  112.     if (lpszString == NULL)
  113.         return NULL;
  114.  
  115.     // Convert from ANSI to UNICODE
  116.     nLen = lstrlen(lpszString) + 1;
  117.     lpszResult = (LPOLESTR)CoTaskMemAlloc(nLen * sizeof(OLECHAR));
  118.     if (lpszResult)    {
  119. #ifdef _WIN32
  120.         MultiByteToWideChar(CP_ACP, 0, lpszString, -1, lpszResult, nLen);
  121. #else
  122.         lstrcpy(lpszResult, lpszString);  // Win 16 doesn't use any UNICODE
  123. #endif
  124.     }
  125.  
  126.     return lpszResult;
  127. }
  128.  
  129. /////////////////////////////////////////////////////////////////////////////
  130. // CEnumHelpers
  131.  
  132. // Helper class to encapsulate enumeration of the helper apps
  133. class CEnumHelpers : public IEnumHelpers {
  134.     public:
  135.         CEnumHelpers();
  136.         
  137.         // IUnknown methods
  138.         STDMETHODIMP QueryInterface(REFIID riid, LPVOID FAR* ppvObj);
  139.         STDMETHODIMP_(ULONG) AddRef();
  140.         STDMETHODIMP_(ULONG) Release();
  141.  
  142.         // IEnumHelpers methods
  143.         STDMETHODIMP         Next(NET_cdataStruct **ppcdata);
  144.         STDMETHODIMP         Reset();
  145.  
  146.     private:
  147.         ULONG        m_uRef;
  148.         XP_List       *m_pInfoList;
  149. };
  150.  
  151. CEnumHelpers::CEnumHelpers()
  152. {
  153.     m_uRef = 0;
  154.     m_pInfoList = cinfo_MasterListPointer();
  155. }
  156.  
  157. STDMETHODIMP
  158. CEnumHelpers::QueryInterface(REFIID riid, LPVOID FAR* ppvObj)
  159. {
  160.     *ppvObj = NULL;
  161.  
  162.     if (riid == IID_IUnknown || riid == IID_IEnumHelpers) {
  163.         *ppvObj = (LPVOID)this;
  164.         AddRef();
  165.         return NOERROR;
  166.     }
  167.  
  168.     return ResultFromScode(E_NOINTERFACE);
  169. }
  170.  
  171. STDMETHODIMP_(ULONG)
  172. CEnumHelpers::AddRef()
  173. {
  174.     return ++m_uRef;
  175. }
  176.  
  177. STDMETHODIMP_(ULONG)
  178. CEnumHelpers::Release()
  179. {
  180.     if (--m_uRef == 0) {
  181.         delete this;
  182.         return 0;
  183.     }
  184.  
  185.     return m_uRef;
  186. }
  187.  
  188. STDMETHODIMP
  189. CEnumHelpers::Next(NET_cdataStruct **ppcdata)
  190. {
  191.     CHelperApp    *pHelperApp;
  192.  
  193.     while ((*ppcdata = (NET_cdataStruct *)XP_ListNextObject(m_pInfoList))) {
  194.         // Ignore items that don't have a MIME type
  195.         if (!(*ppcdata)->ci.type)
  196.             continue;
  197.  
  198.         // Don't give the user an opportunity to change application/octet-stream
  199.         // or proxy auto-config
  200.         if (strcmp((*ppcdata)->ci.type, APPLICATION_OCTET_STREAM) == 0 ||
  201.             strcmp((*ppcdata)->ci.type, APPLICATION_NS_PROXY_AUTOCONFIG) == 0) {
  202.             continue;
  203.         }
  204.  
  205.         // Ignore items that don't have a description
  206.         if (!(*ppcdata)->ci.desc) {
  207. #ifdef DEBUG
  208.             TRACE1("PREFS: Ignoring MIME type %s\n", (*ppcdata)->ci.type);
  209. #endif
  210.             continue;
  211.         }
  212.         
  213.         // Make sure there's a CHelperApp associated with the item
  214.         pHelperApp = (CHelperApp *)(*ppcdata)->ci.fe_data;
  215.  
  216.         if (!pHelperApp) {
  217. #ifdef DEBUG
  218.             TRACE1("PREFS: Ignoring MIME type %s\n", (*ppcdata)->ci.type);
  219. #endif
  220.             continue;
  221.         }
  222.  
  223.         // Ignore items that have HANDLE_UNKNOWN or HANDLE_MOREINFO as how to handle
  224.         if (pHelperApp->how_handle == HANDLE_UNKNOWN || pHelperApp->how_handle == HANDLE_MOREINFO) {
  225. #ifdef DEBUG
  226.             TRACE1("PREFS: Ignoring MIME type %s\n", (*ppcdata)->ci.type);
  227. #endif
  228.             continue;
  229.         }
  230.  
  231.         return NOERROR;
  232.     }
  233.  
  234.     return ResultFromScode(S_FALSE);
  235. }
  236.  
  237. STDMETHODIMP
  238. CEnumHelpers::Reset()
  239. {
  240.     m_pInfoList = cinfo_MasterListPointer();
  241.     return NOERROR;
  242. }
  243.  
  244. /////////////////////////////////////////////////////////////////////////////
  245. // CBrowserPrefs
  246.  
  247. class CBrowserPrefs : public IBrowserPrefs {
  248.     public:
  249.         CBrowserPrefs(LPCSTR lpszCurrentPage);
  250.  
  251.         // IUnknown methods
  252.         STDMETHODIMP QueryInterface(REFIID riid, LPVOID FAR* ppvObj);
  253.         STDMETHODIMP_(ULONG) AddRef();
  254.         STDMETHODIMP_(ULONG) Release();
  255.         
  256.         // IBrowserPrefs methods
  257.         STDMETHODIMP GetCurrentPage(LPOLESTR *lpoleStr);
  258.  
  259.         STDMETHODIMP EnumHelpers(LPENUMHELPERS *ppenumHelpers);
  260.         STDMETHODIMP GetHelperInfo(NET_cdataStruct *, LPHELPERINFO);
  261.         STDMETHODIMP SetHelperInfo(NET_cdataStruct *, LPHELPERINFO);
  262.         STDMETHODIMP NewFileType(LPCSTR lpszDescription,
  263.                                  LPCSTR lpszExtension,
  264.                                  LPCSTR lpszMimeType,
  265.                                  LPCSTR lpszOpenCmd,
  266.                                  NET_cdataStruct **ppcdata);
  267.         STDMETHODIMP RemoveFileType(NET_cdataStruct *);
  268.  
  269.         // Initialization routine to create contained and aggregated objects
  270.         HRESULT         Init();
  271.  
  272.     private:
  273.         ULONG          m_uRef;
  274.         LPUNKNOWN     m_pCategory;  // inner object supporting ISpecifyPropertyPageObjects
  275.         LPCSTR        m_lpszCurrentPage;
  276. };
  277.  
  278. CBrowserPrefs::CBrowserPrefs(LPCSTR lpszCurrentPage)
  279. {
  280.     m_uRef = 0;
  281.     m_pCategory = NULL;
  282.     m_lpszCurrentPage = lpszCurrentPage ? strdup(lpszCurrentPage) : NULL;
  283. }
  284.  
  285. HRESULT
  286. CBrowserPrefs::Init()
  287. {
  288.     // Create the object as part of an aggregate
  289.     return CoCreateInstance(CLSID_BrowserPrefs, (LPUNKNOWN)this,
  290.         CLSCTX_INPROC_SERVER, IID_IUnknown, (LPVOID *)&m_pCategory);
  291. }
  292.  
  293. STDMETHODIMP
  294. CBrowserPrefs::QueryInterface(REFIID riid, LPVOID FAR* ppvObj)
  295. {
  296.     *ppvObj = NULL;
  297.  
  298.     if (riid == IID_IUnknown || riid == IID_IBrowserPrefs) {
  299.         *ppvObj = (LPVOID)this;
  300.         AddRef();
  301.         return NOERROR;
  302.  
  303.     } else if (riid == IID_ISpecifyPropertyPageObjects) {
  304.         assert(m_pCategory);
  305.         return m_pCategory->QueryInterface(riid, ppvObj);
  306.     }
  307.  
  308.     return ResultFromScode(E_NOINTERFACE);
  309. }
  310.  
  311. STDMETHODIMP_(ULONG)
  312. CBrowserPrefs::AddRef()
  313. {
  314.     return ++m_uRef;
  315. }
  316.  
  317. STDMETHODIMP_(ULONG)
  318. CBrowserPrefs::Release()
  319. {
  320.     if (--m_uRef == 0) {
  321.         if (m_pCategory)
  322.             m_pCategory->Release();
  323.         if (m_lpszCurrentPage)
  324.             XP_FREE((void *)m_lpszCurrentPage);
  325.         delete this;
  326.         return 0;
  327.     }
  328.  
  329.     return m_uRef;
  330. }
  331.  
  332. STDMETHODIMP
  333. CBrowserPrefs::GetCurrentPage(LPOLESTR *lpoleStr)
  334. {
  335.     if (!lpoleStr)
  336.         return ResultFromScode(E_INVALIDARG);
  337.     
  338.     *lpoleStr = 0;
  339.  
  340.     if (m_lpszCurrentPage) {
  341.         *lpoleStr = AllocTaskOleString(m_lpszCurrentPage);
  342.         
  343.         if (!*lpoleStr)
  344.             return ResultFromScode(E_OUTOFMEMORY);
  345.     }
  346.  
  347.     return NOERROR;
  348. }
  349.  
  350. STDMETHODIMP
  351. CBrowserPrefs::EnumHelpers(LPENUMHELPERS *ppEnumHelpers)
  352. {
  353.     CEnumHelpers   *pEnumHelpers = new CEnumHelpers;
  354.     HRESULT            hres;
  355.     
  356.     if (!pEnumHelpers)
  357.         return ResultFromScode(E_OUTOFMEMORY);
  358.  
  359.     pEnumHelpers->AddRef();
  360.     hres = pEnumHelpers->QueryInterface(IID_IEnumHelpers, (LPVOID *)ppEnumHelpers);
  361.     pEnumHelpers->Release();
  362.     return hres;
  363. }
  364.  
  365. // Returns the command string value (path and filename for the application plus any
  366. // command line options) associated with the given file extension
  367. static BOOL
  368. GetOpenCommandForExt(LPCSTR lpszExt, LPSTR lpszCmdString, DWORD cbCmdString)
  369. {
  370.     char    szBuf[_MAX_PATH + 32];
  371.     char    szFileClass[60];
  372.     LONG    lResult;
  373.     LONG    lcb;
  374. #ifdef _WIN32
  375.     DWORD    cbData;
  376.     DWORD    dwType;
  377. #else
  378.     LONG    cbData;
  379. #endif
  380.  
  381.     *lpszCmdString = '\0';
  382.     
  383.     // Look up the file association key which maps a file extension
  384.     // to an application identifier (also called the file type class
  385.     // identifier or just file class)
  386.     PR_snprintf(szBuf, sizeof(szBuf), ".%s", lpszExt);
  387.     lcb = sizeof(szFileClass);
  388.     lResult = RegQueryValue(HKEY_CLASSES_ROOT, szBuf, szFileClass, &lcb);
  389.  
  390. #ifdef _WIN32
  391.     ASSERT(lResult != ERROR_MORE_DATA);
  392. #endif
  393.     if (lResult != ERROR_SUCCESS)
  394.         return FALSE;
  395.  
  396.     // Get the key for shell\open\command
  397.     HKEY    hKey;
  398.     
  399. #ifdef _WIN32
  400.     PR_snprintf(szBuf, sizeof(szBuf), "%s\\shell\\open\\command", szFileClass);
  401.     lResult = RegOpenKeyEx(HKEY_CLASSES_ROOT, szBuf, 0, KEY_QUERY_VALUE, &hKey);
  402. #else
  403.     PR_snprintf(szBuf, sizeof(szBuf), "%s\\shell\\open\\command", szFileClass);
  404.     lResult = RegOpenKey(HKEY_CLASSES_ROOT, szBuf, &hKey);
  405. #endif
  406.     if (lResult != ERROR_SUCCESS)
  407.         return FALSE;
  408.  
  409.     // Get the value of the key
  410.     cbData = sizeof(szBuf);
  411. #ifdef _WIN32
  412.     lResult = RegQueryValueEx(hKey, NULL, NULL, &dwType, (LPBYTE)szBuf, &cbData);
  413. #else
  414.     lResult = RegQueryValue(hKey, NULL, (LPSTR)szBuf, &cbData);
  415. #endif
  416.     RegCloseKey(hKey);
  417.     if (lResult != ERROR_SUCCESS)
  418.         return FALSE;
  419.  
  420. #ifdef _WIN32
  421.     // Win32 doesn't expand automatically environment variables (for value
  422.     // data of type REG_EXPAND_SZ). We need this for things like %SystemRoot%
  423.     if (dwType == REG_EXPAND_SZ)
  424.         ExpandEnvironmentStrings(szBuf, lpszCmdString, cbCmdString);
  425.     else
  426.         lstrcpy(lpszCmdString, szBuf);
  427. #else
  428.     lstrcpy(lpszCmdString, szBuf);
  429. #endif
  430.  
  431.     return TRUE;
  432. }
  433.  
  434. // Returns the path of the helper application associated with the
  435. // given pcdata
  436. static BOOL
  437. GetApplication(NET_cdataStruct *pcdata, LPSTR lpszApp)
  438. {
  439.     CHelperApp *pHelperApp = (CHelperApp *)pcdata->ci.fe_data;
  440.     char          *lpszFile;
  441.     char        szExtension[_MAX_EXT];
  442.     LPSTR        lpszStrip;
  443.  
  444.     if (!pHelperApp)
  445.         return FALSE;
  446.  
  447.     // How we do this depends on how it's handled
  448.     switch (pHelperApp->how_handle) {
  449.         case HANDLE_EXTERNAL:
  450.             lstrcpy(lpszApp, (LPCSTR)pHelperApp->csCmd);
  451.  
  452.             // XXX - this is what the code in display.cpp does, but it's really
  453.             // wrong...
  454.             lpszStrip = strrchr(lpszApp, '%');
  455.  
  456.             if (lpszStrip)
  457.                 *lpszStrip = '\0';
  458.             return TRUE;
  459.  
  460.         case HANDLE_SHELLEXECUTE:
  461.         case HANDLE_BY_OLE:
  462.             // Have FindExecutable() tell us what the executable name is
  463.             wsprintf(szExtension, ".%s", pcdata->exts[0]);
  464.             lpszFile = WH_TempFileName(xpTemporary, "M", szExtension);
  465.             if (lpszFile) {
  466.                 BOOL    bResult = FEU_FindExecutable(lpszFile, lpszApp, TRUE);
  467.  
  468.                 XP_FREE(lpszFile);
  469.                 return bResult;
  470.             }
  471.             return FALSE;
  472.  
  473.         default:
  474.             ASSERT(FALSE);
  475.             return FALSE;
  476.     }
  477. }
  478.  
  479. //Begin CRN_MIME
  480. static BOOL
  481. IsMimeTypeLocked(const char *pPrefix)
  482. {
  483.     BOOL bRet = FALSE;
  484.  
  485.     //???????Any holes here??????
  486.     //I'm looking at just the ".type" field to see if a pref is locked. 
  487.     char* setup_buf = PR_smprintf("%s.%s", pPrefix, "mimetype");
  488.  
  489.     bRet = PREF_PrefIsLocked(setup_buf);
  490.  
  491.     if(setup_buf && setup_buf[0])
  492.         XP_FREEIF(setup_buf);
  493.  
  494.     return bRet;
  495. }
  496.  
  497. static int
  498. GetPrefLoadAction(int how_handle)
  499. {
  500.     switch(how_handle) {
  501.     case HANDLE_SAVE:
  502.             return 1;
  503.  
  504.         case HANDLE_SHELLEXECUTE: 
  505.             return 2;
  506.  
  507.         case HANDLE_UNKNOWN:
  508.             return 3;
  509.  
  510.         case HANDLE_VIA_PLUGIN:
  511.             return 4;
  512.  
  513.         default:
  514.             return 2;
  515.     }
  516. }
  517. //End CRN_MIME
  518.  
  519. STDMETHODIMP
  520. CBrowserPrefs::GetHelperInfo(NET_cdataStruct *pcdata, LPHELPERINFO lpInfo)
  521. {
  522.     CHelperApp    *pHelperApp;
  523.     char         szApp[_MAX_PATH];
  524.     
  525.     if (!pcdata || !lpInfo)
  526.         return ResultFromScode(E_INVALIDARG);
  527.  
  528.     pHelperApp = (CHelperApp *)pcdata->ci.fe_data;
  529.     if (!pHelperApp)
  530.         return ResultFromScode(E_UNEXPECTED);
  531.  
  532.     //Begin CRN_MIME
  533.     if(! pHelperApp->csMimePrefPrefix.IsEmpty())
  534.     {
  535.         //This is a mime type associcated with a helper for a type specified thru' prefs.
  536.         //Use the csMimePrefPrefix to generate the pref and see if it's locked.
  537.         lpInfo->bIsLocked = IsMimeTypeLocked((LPCSTR)pHelperApp->csMimePrefPrefix);
  538.         
  539.     }
  540.     else
  541.         lpInfo->bIsLocked = FALSE;
  542.     //End CRN_MIME
  543.  
  544.     lpInfo->nHowToHandle = pHelperApp->how_handle;
  545.     lpInfo->szOpenCmd[0] = '\0';
  546.  
  547.     switch (pHelperApp->how_handle) {
  548.         case HANDLE_EXTERNAL:
  549.             lstrcpy(lpInfo->szOpenCmd, (LPCSTR)pHelperApp->csCmd);
  550.             if (GetApplication(pcdata, szApp))
  551.                 lpInfo->bAskBeforeOpening = theApp.m_pSpawn->PromptBeforeOpening(szApp);
  552.             break;
  553.  
  554.         case HANDLE_SHELLEXECUTE:
  555.         case HANDLE_BY_OLE:
  556.             ASSERT(pcdata->num_exts > 0);
  557.             if (pcdata->num_exts > 0) {
  558.                 GetOpenCommandForExt(pcdata->exts[0], lpInfo->szOpenCmd, sizeof(lpInfo->szOpenCmd));
  559.                 if (GetApplication(pcdata, szApp))
  560.                     lpInfo->bAskBeforeOpening = theApp.m_pSpawn->PromptBeforeOpening(szApp);
  561.             }
  562.             break;
  563.  
  564.         case HANDLE_SAVE:
  565.             if (pcdata->num_exts > 0) {
  566.                 // Even though it's marked as Save to Disk get the shell open command anyway. This
  567.                 // way if the user changes the association to launch the application they'll already
  568.                 // have it
  569.                 GetOpenCommandForExt(pcdata->exts[0], lpInfo->szOpenCmd, sizeof(lpInfo->szOpenCmd));
  570.                 lpInfo->bAskBeforeOpening = TRUE;
  571.             }
  572.             break;
  573.  
  574.         default:
  575.             break;
  576.     }
  577.     
  578.     return NOERROR;
  579. }
  580.  
  581. STDMETHODIMP
  582. CBrowserPrefs::SetHelperInfo(NET_cdataStruct *pcdata, LPHELPERINFO lpInfo)
  583. {
  584.     fe_ChangeFileType(pcdata, lpInfo->lpszMimeType, lpInfo->nHowToHandle, lpInfo->szOpenCmd);
  585.  
  586. //Begin CRN_MIME
  587.     //Set user pref values only for mime types setup from the pref file
  588.     CHelperApp    *pHelperApp;
  589.     pHelperApp = (CHelperApp *)pcdata->ci.fe_data;
  590.     if(pHelperApp)
  591.     {
  592.         if(! pHelperApp->csMimePrefPrefix.IsEmpty())
  593.         {
  594.             char* setup_buf = PR_smprintf("%s.%s", (LPCSTR)pHelperApp->csMimePrefPrefix, "mimetype");
  595.             PREF_SetCharPref(setup_buf, lpInfo->lpszMimeType);
  596.             if(setup_buf && setup_buf[0])
  597.                 XP_FREEIF(setup_buf);
  598.  
  599.             setup_buf = PR_smprintf("%s.%s", (LPCSTR)pHelperApp->csMimePrefPrefix, "win_appname");
  600.             PREF_SetCharPref(setup_buf, lpInfo->szOpenCmd);
  601.             if(setup_buf && setup_buf[0])
  602.                 XP_FREEIF(setup_buf);
  603.  
  604.             setup_buf = PR_smprintf("%s.%s", (LPCSTR)pHelperApp->csMimePrefPrefix, "load_action");
  605.             PREF_SetIntPref(setup_buf, GetPrefLoadAction(lpInfo->nHowToHandle));
  606.             if(setup_buf && setup_buf[0])
  607.                 XP_FREEIF(setup_buf);
  608.         }
  609.     }
  610.  
  611. //End CRN_MIME
  612.  
  613.     if (lpInfo->nHowToHandle == HANDLE_EXTERNAL ||
  614.         lpInfo->nHowToHandle == HANDLE_SHELLEXECUTE ||
  615.         lpInfo->nHowToHandle == HANDLE_BY_OLE) {
  616.  
  617.         // Update whether we should prompt before opening the file
  618.         char    szApp[_MAX_PATH];
  619.  
  620.         if (GetApplication(pcdata, szApp))
  621.             theApp.m_pSpawn->SetPromptBeforeOpening(szApp, lpInfo->bAskBeforeOpening);
  622.     }
  623.     return NOERROR;
  624. }
  625.  
  626. STDMETHODIMP
  627. CBrowserPrefs::NewFileType(LPCSTR lpszDescription,
  628.                            LPCSTR lpszExtension,
  629.                            LPCSTR lpszMimeType,
  630.                            LPCSTR lpszOpenCmd,
  631.                            NET_cdataStruct **ppcdata)
  632. {
  633.     *ppcdata = fe_NewFileType(lpszDescription, lpszExtension, lpszMimeType, lpszOpenCmd);
  634.     return *ppcdata ? NOERROR : ResultFromScode(S_FALSE);
  635. }
  636.  
  637. STDMETHODIMP
  638. CBrowserPrefs::RemoveFileType(NET_cdataStruct *pcdata)
  639. {
  640. //Begin CRN_MIME
  641.     //Clear user pref values only for mime types setup from the pref file
  642.     CHelperApp    *pHelperApp;
  643.     pHelperApp = (CHelperApp *)pcdata->ci.fe_data;
  644.     if(pHelperApp)
  645.     {
  646.         if(! pHelperApp->csMimePrefPrefix.IsEmpty())
  647.         {
  648.             char* setup_buf = PR_smprintf("%s.%s", (LPCSTR)pHelperApp->csMimePrefPrefix, "mimetype");
  649.             PREF_ClearUserPref(setup_buf);
  650.             if(setup_buf && setup_buf[0])
  651.                 XP_FREEIF(setup_buf);
  652.  
  653.             setup_buf = PR_smprintf("%s.%s", (LPCSTR)pHelperApp->csMimePrefPrefix, "win_appname");
  654.             PREF_ClearUserPref(setup_buf);
  655.             if(setup_buf && setup_buf[0])
  656.                 XP_FREEIF(setup_buf);
  657.  
  658.             setup_buf = PR_smprintf("%s.%s", (LPCSTR)pHelperApp->csMimePrefPrefix, "load_action");
  659.             PREF_ClearUserPref(setup_buf);
  660.             if(setup_buf && setup_buf[0])
  661.                 XP_FREEIF(setup_buf);
  662.  
  663.             setup_buf = PR_smprintf("%s.%s", (LPCSTR)pHelperApp->csMimePrefPrefix, "extension");
  664.             PREF_ClearUserPref(setup_buf);
  665.             if(setup_buf && setup_buf[0])
  666.                 XP_FREEIF(setup_buf);
  667.  
  668.             setup_buf = PR_smprintf("%s.%s", (LPCSTR)pHelperApp->csMimePrefPrefix, "description");
  669.             PREF_ClearUserPref(setup_buf);
  670.             if(setup_buf && setup_buf[0])
  671.                 XP_FREEIF(setup_buf);
  672.         }
  673.     }
  674. //End CRN_MIME
  675.  
  676.     return fe_RemoveFileType(pcdata) ? NOERROR : ResultFromScode(S_FALSE);
  677. }
  678.  
  679. /////////////////////////////////////////////////////////////////////////////
  680. // CAppearancePreferences
  681.  
  682. class CAppearancePrefs : public IIntlFont {
  683.     public:
  684.         CAppearancePrefs(int nCharsetId);
  685.  
  686.         // IUnknown methods
  687.         STDMETHODIMP QueryInterface(REFIID riid, LPVOID FAR* ppvObj);
  688.         STDMETHODIMP_(ULONG) AddRef();
  689.         STDMETHODIMP_(ULONG) Release();
  690.         
  691.         // IIntlFont methods
  692.         STDMETHODIMP GetNumEncodings(LPDWORD pdwEncodings);
  693.         STDMETHODIMP GetEncodingName(DWORD dwCharsetNum, LPOLESTR *pszName);
  694.         STDMETHODIMP GetEncodingInfo(DWORD dwCharsetNum, LPENCODINGINFO lpInfo);
  695.         STDMETHODIMP SetEncodingFonts(DWORD dwCharsetNum, LPENCODINGINFO lpInfo);
  696.         STDMETHODIMP GetCurrentCharset(LPDWORD pdwCharsetNum);
  697.  
  698.         // Initialization routine to create contained and aggregated objects
  699.         HRESULT         Init();
  700.  
  701.     private:
  702.         ULONG      m_uRef;
  703.         int          m_nCharsetId;
  704.         LPUNKNOWN m_pCategory;  // inner object supporting ISpecifyPropertyPageObjects
  705. };
  706.  
  707. CAppearancePrefs::CAppearancePrefs(int nCharsetId)
  708. {
  709.     m_uRef = 0;
  710.     m_nCharsetId = nCharsetId;
  711.     m_pCategory = NULL;
  712. }
  713.  
  714. HRESULT
  715. CAppearancePrefs::Init()
  716. {
  717.     // Create the object as part of an aggregate
  718.     return CoCreateInstance(CLSID_AppearancePrefs, (LPUNKNOWN)this,
  719.         CLSCTX_INPROC_SERVER, IID_IUnknown, (LPVOID *)&m_pCategory);
  720. }
  721.  
  722. STDMETHODIMP
  723. CAppearancePrefs::QueryInterface(REFIID riid, LPVOID FAR* ppvObj)
  724. {
  725.     *ppvObj = NULL;
  726.  
  727.     if (riid == IID_IUnknown || riid == IID_IIntlFont) {
  728.         *ppvObj = (LPVOID)this;
  729.         AddRef();
  730.         return NOERROR;
  731.  
  732.     } else if (riid == IID_ISpecifyPropertyPageObjects) {
  733.         assert(m_pCategory);
  734.         return m_pCategory->QueryInterface(riid, ppvObj);
  735.     }
  736.  
  737.     return ResultFromScode(E_NOINTERFACE);
  738. }
  739.  
  740. STDMETHODIMP_(ULONG)
  741. CAppearancePrefs::AddRef()
  742. {
  743.     return ++m_uRef;
  744. }
  745.  
  746. STDMETHODIMP_(ULONG)
  747. CAppearancePrefs::Release()
  748. {
  749.     if (--m_uRef == 0) {
  750.         if (m_pCategory)
  751.             m_pCategory->Release();
  752.         delete this;
  753.         return 0;
  754.     }
  755.  
  756.     return m_uRef;
  757. }
  758.  
  759. STDMETHODIMP
  760. CAppearancePrefs::GetNumEncodings(LPDWORD pdwEncodings)
  761. {
  762.     if (!pdwEncodings)
  763.         return ResultFromScode(E_INVALIDARG);
  764.     
  765.     *pdwEncodings = (DWORD)MAXLANGNUM;
  766.     return NOERROR;
  767. }
  768.  
  769. STDMETHODIMP
  770. CAppearancePrefs::GetEncodingName(DWORD dwCharsetNum, LPOLESTR *lpoleName)
  771. {
  772.     if (dwCharsetNum >= (DWORD)MAXLANGNUM || !lpoleName)
  773.         return ResultFromScode(E_INVALIDARG);
  774.  
  775.     LPCSTR    lpszName = theApp.m_pIntlFont->GetEncodingName((int)dwCharsetNum);
  776.  
  777.     if (lpszName) {
  778.         *lpoleName = AllocTaskOleString(lpszName);
  779.         return *lpoleName ? NOERROR : ResultFromScode(E_OUTOFMEMORY);
  780.     }
  781.     
  782.     return ResultFromScode(E_UNEXPECTED);
  783. }
  784.  
  785. STDMETHODIMP
  786. CAppearancePrefs::GetEncodingInfo(DWORD dwCharsetNum, LPENCODINGINFO lpInfo)
  787. {
  788.     EncodingInfo    *lpEncoding;
  789.  
  790.     if (dwCharsetNum >= (DWORD)MAXLANGNUM || !lpInfo)
  791.         return ResultFromScode(E_INVALIDARG);
  792.     
  793.     lpEncoding = theApp.m_pIntlFont->GetEncodingInfo((int)dwCharsetNum);
  794.     lpInfo->bIgnorePitch = ( CIntlWin::FontSelectIgnorePitch(lpEncoding->iCSID) );
  795.     lstrcpy(lpInfo->szVariableWidthFont, lpEncoding->szPropName);
  796.     lpInfo->nVariableWidthSize = lpEncoding->iPropSize;
  797.     lstrcpy(lpInfo->szFixedWidthFont, lpEncoding->szFixName);
  798.     lpInfo->nFixedWidthSize = lpEncoding->iFixSize;
  799.     return NOERROR;
  800. }
  801.  
  802. STDMETHODIMP
  803. CAppearancePrefs::SetEncodingFonts(DWORD dwCharsetNum, LPENCODINGINFO lpInfo)
  804. {
  805.     EncodingInfo   *lpEncoding;
  806.     BOOL            bFixedWidthChanged;
  807.     BOOL            bVariableWidthChanged;
  808.  
  809.     if (dwCharsetNum >= (DWORD)MAXLANGNUM || !lpInfo)
  810.         return ResultFromScode(E_INVALIDARG);
  811.     
  812.     lpEncoding = theApp.m_pIntlFont->GetEncodingInfo((int)dwCharsetNum);
  813.  
  814.     // See if anything has changed. We don't want to reset everything
  815.     // if nothing has changed
  816.     bFixedWidthChanged = lstrcmp(lpInfo->szFixedWidthFont, lpEncoding->szFixName) != 0 ||
  817.         lpInfo->nFixedWidthSize != lpEncoding->iFixSize;
  818.     bVariableWidthChanged = lstrcmp(lpInfo->szVariableWidthFont, lpEncoding->szPropName) != 0 ||
  819.         lpInfo->nVariableWidthSize != lpEncoding->iPropSize;
  820.  
  821.     if (bFixedWidthChanged || bVariableWidthChanged) {
  822.         lstrcpy(lpEncoding->szFixName, lpInfo->szFixedWidthFont);
  823.         lpEncoding->iFixSize = lpInfo->nFixedWidthSize;
  824.         lstrcpy(lpEncoding->szPropName, lpInfo->szVariableWidthFont);
  825.         lpEncoding->iPropSize = lpInfo->nVariableWidthSize;
  826.         
  827.         // Reset the assorted font caches...
  828.         CDCCX::ClearAllFontCaches();
  829.         CVirtualFontFontCache::Reset();
  830.         theApp.m_pIntlFont->WriteToIniFile();
  831.  
  832.         // Indicate we need to reload all of the windows
  833.         g_bReloadAllWindows = TRUE;
  834.     }
  835.     
  836.     return NOERROR;
  837. }
  838.  
  839. STDMETHODIMP
  840. CAppearancePrefs::GetCurrentCharset(LPDWORD pdwCharsetNum)
  841. {
  842.     if (!pdwCharsetNum)
  843.         return ResultFromScode(E_INVALIDARG);
  844.  
  845.     *pdwCharsetNum = (DWORD)m_nCharsetId;
  846.     return NOERROR;
  847. }
  848.  
  849. #ifdef MOZ_MAIL_NEWS
  850. /////////////////////////////////////////////////////////////////////////////
  851. // CMailNewsPreferences
  852.  
  853. class CMailNewsPreferences : public IMailNewsInterface {
  854.     public:
  855.         CMailNewsPreferences();
  856.         ~CMailNewsPreferences();
  857.  
  858.         // IUnknown methods
  859.         STDMETHODIMP QueryInterface(REFIID riid, LPVOID FAR* ppvObj);
  860.         STDMETHODIMP_(ULONG) AddRef();
  861.         STDMETHODIMP_(ULONG) Release();
  862.         
  863.         // IMailNewsInterface methods
  864.         STDMETHODIMP_(BOOL) CreateAddressBookCard(HWND hParent);
  865.         STDMETHODIMP EditAddressBookCard(HWND hParent);
  866.  
  867.         STDMETHODIMP GetSigFile(HWND hParent, LPOLESTR *pszSigFile);
  868.         STDMETHODIMP ShowDirectoryPicker(HWND hParent, LPOLESTR lpIniDir, LPOLESTR *pszNewDir);
  869.  
  870.         STDMETHODIMP ShowChooseFolder(HWND hParent, LPOLESTR lpFolderPath, DWORD dwType, 
  871.                         LPOLESTR *lpFolder, LPOLESTR *lpServer, LPOLESTR *lpPref);
  872.         STDMETHODIMP GetFolderServer(LPOLESTR lpFolderPath, DWORD dwType, 
  873.                         LPOLESTR *lpFolder, LPOLESTR *lpServer);
  874.         
  875.         STDMETHODIMP FillNewsServerList(HWND hControl, LPOLESTR lpServerName);
  876.         STDMETHODIMP GetNewsServerName(HWND hControl, LPOLESTR *lpServerName);
  877.         STDMETHODIMP_(BOOL) AddNewsServer(HWND hParent, HWND hControl);
  878.         STDMETHODIMP_(BOOL) EditNewsServer(HWND hParent, HWND hControl, BOOL *pChanged);
  879.         STDMETHODIMP DeleteNewsServer(HWND hParent, HWND hControl);
  880.  
  881.         STDMETHODIMP_(BOOL) AddMailServer(HWND hParent, HWND hControl, BOOL bAllowBoth, DWORD dwType);
  882.         STDMETHODIMP_(BOOL) EditMailServer(HWND hParent, HWND hControl, BOOL bAllowBoth, DWORD dwType);
  883.         STDMETHODIMP_(BOOL) DeleteMailServer(HWND hParent, HWND hControl, DWORD dwType);
  884.  
  885.         STDMETHODIMP FillLdapDirList(HWND hControl, LPOLESTR lpServerName);
  886.         STDMETHODIMP SetLdapDirAutoComplete(HWND hControl, BOOL bOnOrOff);
  887.  
  888.         // Initialization routine to create contained and aggregated objects
  889.         HRESULT         Init();
  890.  
  891.     private:
  892.  
  893.         ULONG      m_uRef;
  894.         LPUNKNOWN m_pCategory;  // inner object supporting ISpecifyPropertyPageObjects
  895.  
  896.         BOOL m_bStaticCtl;
  897.         int m_iInitialDepth;
  898.         LPIMAGEMAP m_pIImageMap;
  899.         LPUNKNOWN m_pIImageUnk;
  900.         HFONT m_hFont, m_hBoldFont;
  901.         XP_List    *m_pLdapServers;
  902.         MSG_NewsHost** m_hNewsHost;
  903. };
  904.  
  905. /////////////////////////////////////////////////////////////////////////////
  906. // CMailNewsPreferences
  907.  
  908. CMailNewsPreferences::CMailNewsPreferences()
  909. {
  910.     m_uRef = 0;
  911.     m_pCategory = NULL;
  912.     m_pIImageMap = NULL;
  913.     m_pIImageUnk = NULL;
  914.     m_hFont = NULL;
  915.     m_hBoldFont = NULL;
  916.     m_pLdapServers = NULL;
  917.     m_hNewsHost = NULL;
  918.  
  919.     char location[256];
  920.     int nLen = 255;
  921.  
  922.     m_pLdapServers = XP_ListNew();
  923.     PREF_GetDefaultCharPref("browser.addressbook_location", location, &nLen);
  924.     DIR_GetServerPreferences (&m_pLdapServers, location);
  925. }
  926.  
  927. CMailNewsPreferences::~CMailNewsPreferences()
  928. {
  929.     if (m_pIImageUnk && m_pIImageMap ) {
  930.         m_pIImageUnk->Release();
  931.     }
  932.     if (m_hFont)
  933.         theApp.ReleaseAppFont(m_hFont);
  934.     if (m_hBoldFont)
  935.         theApp.ReleaseAppFont(m_hBoldFont);
  936.     if (m_pLdapServers)
  937.     {
  938.         DIR_DeleteServerList(m_pLdapServers);
  939.         m_pLdapServers = NULL;
  940.     }
  941.     if (m_hNewsHost)
  942.         delete [] m_hNewsHost;
  943.     m_hNewsHost = NULL;
  944. }
  945.  
  946. HRESULT
  947. CMailNewsPreferences::Init()
  948. {
  949.  
  950.     // Create the object as part of an aggregate
  951.     return CoCreateInstance(CLSID_MailNewsPrefs, (LPUNKNOWN)this,
  952.         CLSCTX_INPROC_SERVER, IID_IUnknown, (LPVOID *)&m_pCategory);
  953. }
  954.  
  955. STDMETHODIMP
  956. CMailNewsPreferences::QueryInterface(REFIID riid, LPVOID FAR* ppvObj)
  957. {
  958.     *ppvObj = NULL;
  959.  
  960.     if (riid == IID_IUnknown || riid == IID_MailNewsInterface) {
  961.         *ppvObj = (LPVOID)this;
  962.         AddRef();
  963.         return NOERROR;
  964.  
  965.     } else if (riid == IID_ISpecifyPropertyPageObjects) {
  966.         assert(m_pCategory);
  967.         return m_pCategory->QueryInterface(riid, ppvObj);
  968.     }
  969.  
  970.     return ResultFromScode(E_NOINTERFACE);
  971. }
  972.  
  973. STDMETHODIMP_(ULONG)
  974. CMailNewsPreferences::AddRef()
  975. {
  976.     return ++m_uRef;
  977. }
  978.  
  979. STDMETHODIMP_(ULONG)
  980. CMailNewsPreferences::Release()
  981. {
  982.     if (--m_uRef == 0) {
  983.         if (m_pCategory)
  984.             m_pCategory->Release();
  985.         delete this;
  986.         return 0;
  987.     }
  988.  
  989.     return m_uRef;
  990. }
  991.  
  992.  
  993. STDMETHODIMP_(BOOL)
  994. CMailNewsPreferences::CreateAddressBookCard(HWND hParent)
  995. {
  996.     char* email = NULL;
  997.     char* name = NULL;
  998.     PersonEntry person;
  999.     person.Initialize();
  1000.     ABID entryID;
  1001.     DIR_Server *pab = NULL;
  1002.     CWnd parent;
  1003.     BOOL result = TRUE;
  1004.  
  1005. #ifdef FEATURE_ADDRPROP
  1006.     parent.Attach(hParent);
  1007.  
  1008.     if (FE_UsersMailAddress())
  1009.         email = XP_STRDUP (FE_UsersMailAddress());
  1010.     if (FE_UsersFullName())
  1011.         name = XP_STRDUP (FE_UsersFullName());
  1012.     person.pGivenName = name;
  1013.     person.pEmailAddress = email;
  1014.     DIR_GetPersonalAddressBook (theApp.m_directories, &pab);
  1015.     XP_ASSERT (pab);
  1016.  
  1017.     if (pab) 
  1018.     {
  1019.         AB_GetEntryIDForPerson(pab, theApp.m_pABook, &entryID, &person);
  1020.  
  1021.         if (entryID == MSG_MESSAGEIDNONE) 
  1022.         {
  1023.             CDialog createCardDlg(IDD_PREF_MNCREATECARD, NULL);
  1024.             if (IDOK == createCardDlg.DoModal())
  1025.             {
  1026.                 CString formattedString;
  1027.                 if (name)
  1028.                     formattedString.Format(XP_GetString (MK_ADDR_BOOK_CARD), name);
  1029.                 else
  1030.                     formattedString = XP_GetString (MK_ADDR_NEW_CARD);
  1031.                 CAddrEditProperties prop(NULL, pab,
  1032.                     (const char *) formattedString, &parent, 0, &person);
  1033.                 prop.SetCurrentPage(0);
  1034.                 if (prop.DoModal() == IDCANCEL)
  1035.                     result = FALSE;
  1036.             }
  1037.             else
  1038.             {
  1039.                 result = FALSE;
  1040.             }
  1041.         }
  1042.     }
  1043.     parent.Detach();
  1044. #endif
  1045.     return result;
  1046. }
  1047.  
  1048. STDMETHODIMP
  1049. CMailNewsPreferences::EditAddressBookCard(HWND hParent)
  1050. {
  1051. #ifdef FEATURE_ADDRPROP
  1052.     char* email = NULL;
  1053.     char* name = NULL;
  1054.     PersonEntry person;
  1055.     person.Initialize();
  1056.     ABID entryID;
  1057.     DIR_Server *pab = NULL;
  1058.     CWnd parent;
  1059.  
  1060.     parent.Attach(hParent);
  1061.  
  1062.     if (FE_UsersMailAddress())
  1063.         email = XP_STRDUP (FE_UsersMailAddress());
  1064.     if (FE_UsersFullName())
  1065.         name = XP_STRDUP (FE_UsersFullName());
  1066.     person.pGivenName = name;
  1067.     person.pEmailAddress = email;
  1068.     DIR_GetPersonalAddressBook (theApp.m_directories, &pab);
  1069.     XP_ASSERT (pab);
  1070.  
  1071.     if (pab) 
  1072.     {
  1073.         AB_GetEntryIDForPerson(pab, theApp.m_pABook, &entryID, &person);
  1074.  
  1075.         if (entryID != MSG_MESSAGEIDNONE) 
  1076.         {
  1077.             CString formattedString;
  1078.             char fullname [kMaxFullNameLength];
  1079.             AB_GetFullName(pab, theApp.m_pABook, entryID, fullname);
  1080.             formattedString.Format(XP_GetString (MK_ADDR_BOOK_CARD), fullname);
  1081.             CAddrEditProperties prop(NULL, pab,
  1082.                 (const char *) formattedString, &parent, entryID);
  1083.             prop.SetCurrentPage(0);
  1084.             prop.DoModal();
  1085.         }
  1086.         else 
  1087.         {
  1088.             CString formattedString;
  1089.             formattedString.Format(XP_GetString (MK_ADDR_BOOK_CARD), name);
  1090.             CAddrEditProperties prop(NULL, pab,
  1091.                 (const char *) formattedString, &parent, 0, &person);
  1092.             prop.SetCurrentPage(0);
  1093.             prop.DoModal();
  1094.         }
  1095.     }
  1096.  
  1097.     if (email)
  1098.             XP_FREE (email);
  1099.     if (name)
  1100.             XP_FREE (name);
  1101.     parent.Detach();
  1102. #endif
  1103.     return NOERROR;
  1104. }
  1105.  
  1106. STDMETHODIMP
  1107. CMailNewsPreferences::GetSigFile(HWND hParent, LPOLESTR *lpoleStr)
  1108. {
  1109.     char* pName = NULL;
  1110.  
  1111.     if (!lpoleStr)
  1112.         return ResultFromScode(E_INVALIDARG);
  1113.     
  1114.     pName = wfe_GetExistingFileName(hParent, szLoadString(IDS_SIG_FILE), 
  1115.                                     ALL, TRUE);
  1116.     *lpoleStr = 0;
  1117.  
  1118.     if (pName)
  1119.     {
  1120.         *lpoleStr = AllocTaskOleString(pName);
  1121.         
  1122.         if (!*lpoleStr)
  1123.             return ResultFromScode(E_OUTOFMEMORY);
  1124.     }
  1125.  
  1126.     return NOERROR;
  1127. }
  1128.  
  1129. STDMETHODIMP CMailNewsPreferences::ShowDirectoryPicker
  1130. (HWND hParent, LPOLESTR lpIniDir, LPOLESTR *pszNewDir)
  1131. {
  1132.     CWnd parent;
  1133.     parent.Attach(hParent);
  1134.  
  1135.     *pszNewDir = 0;
  1136.  
  1137.     CDirDialog directory(&parent, (char*)lpIniDir);
  1138.     if (IDOK == directory.DoModal())
  1139.     {
  1140.         CString fileName = directory.GetPathName();
  1141.         int nPos = fileName.GetLength() - strlen("\\k5bg");
  1142.         CString pathName(fileName.Left(nPos));
  1143.  
  1144.         *pszNewDir = AllocTaskOleString(LPCTSTR(pathName));
  1145.         
  1146.         if (!*pszNewDir)
  1147.             return ResultFromScode(E_OUTOFMEMORY);
  1148.     }
  1149.     parent.Detach();
  1150.     return NOERROR;
  1151. }
  1152.  
  1153. STDMETHODIMP CMailNewsPreferences::ShowChooseFolder
  1154. (HWND hParent, LPOLESTR lpFolderPath, DWORD dwType, LPOLESTR *lpFolder, 
  1155.  LPOLESTR *lpServer, LPOLESTR *lpPref)
  1156. {
  1157.     char* lpPath = (char*)lpFolderPath;
  1158.     int nDefaultID;
  1159.     if (dwType == TYPE_SENT)
  1160.         nDefaultID = MK_MSG_SENT_L10N_NAME;
  1161.     else if (dwType == TYPE_DRAFT)
  1162.         nDefaultID = MK_MSG_DRAFTS_L10N_NAME;
  1163.     else if (dwType == TYPE_TEMPLATE)
  1164.         nDefaultID = MK_MSG_TEMPLATES_L10N_NAME;
  1165.     CWnd parent;
  1166.     parent.Attach(hParent);
  1167.     CChooseFolderDialog folderDialog(&parent, lpPath, nDefaultID);
  1168.     if (IDOK == folderDialog.DoModal())
  1169.     {
  1170.          *lpFolder = AllocTaskOleString(LPCTSTR(folderDialog.m_szFolder));
  1171.          *lpServer = AllocTaskOleString(LPCTSTR(folderDialog.m_szServer));
  1172.          *lpPref = AllocTaskOleString(LPCTSTR(folderDialog.m_szPrefUrl));
  1173.     }
  1174.  
  1175.     parent.Detach();
  1176.     return NOERROR;
  1177. }
  1178.  
  1179.  
  1180. STDMETHODIMP CMailNewsPreferences::GetFolderServer
  1181. (LPOLESTR lpFolderPath, DWORD dwType, LPOLESTR *lpFolder, LPOLESTR *lpServer)
  1182. {
  1183.     
  1184.     char* lpPath = (char*)lpFolderPath;
  1185.     int nDefaultID;
  1186.     if (dwType == TYPE_SENT)
  1187.         nDefaultID = MK_MSG_SENT_L10N_NAME;
  1188.     else if (dwType == TYPE_DRAFT)
  1189.         nDefaultID = MK_MSG_DRAFTS_L10N_NAME;
  1190.     else if (dwType == TYPE_TEMPLATE)
  1191.         nDefaultID = MK_MSG_TEMPLATES_L10N_NAME;
  1192.  
  1193.     CString folder;
  1194.     CString server;
  1195.  
  1196.     GetFolderServerNames(lpPath, nDefaultID, folder, server);
  1197.  
  1198.     if (folder.GetLength())
  1199.         *lpFolder = AllocTaskOleString(LPCTSTR(folder));
  1200.     if (server.GetLength())
  1201.         *lpServer = AllocTaskOleString(LPCTSTR(server));
  1202.  
  1203.     return NOERROR;
  1204. }
  1205.  
  1206. STDMETHODIMP CMailNewsPreferences::FillNewsServerList(HWND hControl, LPOLESTR lpServerName)
  1207. {
  1208.     int nDefaultHost = 0;
  1209.     int nSelectedIndex = -1;
  1210.     char* lpPrefName = (char*)lpServerName;
  1211.  
  1212.      MSG_Master * pMaster = WFE_MSGGetMaster();
  1213.     int32 nTotal =  MSG_GetNewsHosts(pMaster, NULL, 0);
  1214.     if (nTotal)
  1215.     {
  1216.         m_hNewsHost = new MSG_NewsHost* [nTotal];
  1217.         MSG_GetNewsHosts(pMaster, m_hNewsHost, nTotal);
  1218.         for (int i = 0; i < nTotal; i++)
  1219.         {
  1220.             int nAddedIndex = (int)SendMessage(hControl, LB_ADDSTRING, 0, 
  1221.                            (LPARAM)(LPCTSTR)MSG_GetNewsHostUIName(m_hNewsHost[i]));
  1222.             if (nAddedIndex != CB_ERR)
  1223.             {
  1224.                 SendMessage(hControl, LB_SETITEMDATA, (WPARAM)nAddedIndex, 
  1225.                             (LPARAM)(DWORD)m_hNewsHost[i]);
  1226.                 const char *pName = MSG_GetNewsHostUIName(m_hNewsHost[i]);
  1227.                 if (!XP_FILENAMECMP(lpPrefName, pName))
  1228.                     nSelectedIndex = nAddedIndex;
  1229.             }
  1230.         }
  1231.         if (nSelectedIndex >= 0)
  1232.             SendMessage(hControl, LB_SETCURSEL, (WPARAM)nSelectedIndex, (LPARAM)0);
  1233.     }    
  1234.     return NOERROR;
  1235. }
  1236.  
  1237. STDMETHODIMP 
  1238. CMailNewsPreferences::GetNewsServerName(HWND hControl, LPOLESTR *lpServerName)
  1239. {
  1240.     int nIndex = (int)SendMessage(hControl, LB_GETCURSEL, 0,0);
  1241.     if (nIndex != CB_ERR)
  1242.     {
  1243.         MSG_NewsHost* pServer = (MSG_NewsHost*)SendMessage(hControl, LB_GETITEMDATA, 
  1244.                                             (WPARAM)nIndex, 0);
  1245.         *lpServerName = AllocTaskOleString(MSG_GetHostUIName((MSG_Host*)pServer));
  1246.     }
  1247.     return NOERROR;
  1248. }
  1249.  
  1250. STDMETHODIMP_(BOOL)
  1251. CMailNewsPreferences::AddNewsServer(HWND hParent, HWND hControl)
  1252. {
  1253.     BOOL result = FALSE;
  1254.     CWnd parent;
  1255.     parent.Attach(hParent);
  1256.  
  1257.     MSG_Host *pNewHost = DoAddNewsServer(&parent, FROM_PREFERENCE);
  1258.     if (pNewHost)
  1259.     {
  1260.         int nIndex = (int)SendMessage(hControl, LB_ADDSTRING, 0, 
  1261.                           (LPARAM)(LPCTSTR)MSG_GetHostUIName(pNewHost));
  1262.         SendMessage(hControl, LB_SETCURSEL, (WPARAM)nIndex, (LPARAM)0);
  1263.         SendMessage(hControl, LB_SETITEMDATA, (WPARAM)nIndex, 
  1264.                     (LPARAM)(DWORD)pNewHost);
  1265.         result = TRUE;
  1266.     }
  1267.     else
  1268.         result = FALSE;
  1269.     parent.Detach();
  1270.     return result;
  1271. }
  1272.  
  1273. STDMETHODIMP_(BOOL)
  1274. CMailNewsPreferences::EditNewsServer(HWND hParent, HWND hControl, BOOL *pChanged)
  1275. {
  1276.     CWnd parent;
  1277.  
  1278.     int nIndex = (int)SendMessage(hControl, LB_GETCURSEL, 0, 0);
  1279.     if (nIndex >= 0)
  1280.     {
  1281.         parent.Attach(hParent);
  1282.         MSG_Host* pServer = (MSG_Host*)SendMessage(hControl, LB_GETITEMDATA, 
  1283.                                                     (WPARAM)nIndex, 0);
  1284.  
  1285.         CNewsServerDialog addServerDialog(&parent, MSG_GetHostUIName(pServer), 
  1286.                                         FROM_PREFERENCE, (MSG_NewsHost*)pServer);
  1287.         if (IDOK == addServerDialog.DoModal())
  1288.         {
  1289.             char* pName = addServerDialog.GetNewsHostName();
  1290.             XP_Bool bSecure = addServerDialog.GetSecure();
  1291.             XP_Bool bAuthentication = addServerDialog.GetAuthentication();
  1292.             int32 nPort = addServerDialog.GetNewsHostPort();
  1293.  
  1294.             // set the new value
  1295.             MSG_SetNewsHostPushAuth ((MSG_NewsHost*)pServer, bAuthentication);
  1296.  
  1297.             *pChanged = TRUE;
  1298.             parent.Detach();
  1299.             return TRUE;
  1300.         }
  1301.         else
  1302.         {
  1303.             parent.Detach();
  1304.             return FALSE;
  1305.         }
  1306.     }
  1307.     return FALSE;
  1308. }
  1309.  
  1310. STDMETHODIMP CMailNewsPreferences::DeleteNewsServer(HWND hParent, HWND hControl)
  1311. {
  1312.     
  1313.     CWnd parent;
  1314.     parent.Attach(hParent);
  1315.     int nIndex = (int)SendMessage(hControl, LB_GETCURSEL, 0, 0);
  1316.     if (nIndex >= 0)
  1317.     {
  1318.         MSG_Host* pServer = (MSG_Host*)SendMessage(hControl, LB_GETITEMDATA, 
  1319.                                                     (WPARAM)nIndex, 0);
  1320.         char* tmp = PR_smprintf(XP_GetString(MK_MSG_REMOVE_HOST_CONFIRM),
  1321.                                 MSG_GetHostUIName(pServer));
  1322.         if (IDOK == parent.MessageBox(tmp, szLoadString(AFX_IDS_APP_TITLE), MB_OKCANCEL))
  1323.         {
  1324.              MSG_Master * pMaster = WFE_MSGGetMaster();
  1325.             MSG_DeleteNewsHost(pMaster, (MSG_NewsHost*)pServer);
  1326.             SendMessage(hControl, LB_DELETESTRING, nIndex, 0);
  1327.         }
  1328.         if(tmp && tmp[0])
  1329.             XP_FREE(tmp);
  1330.     }
  1331.     parent.Detach();
  1332.     
  1333.     return NOERROR;
  1334. }
  1335.  
  1336. STDMETHODIMP_(BOOL) CMailNewsPreferences::AddMailServer
  1337. (HWND hParent, HWND hControl, BOOL bAllowBoth, DWORD dwType)
  1338. {
  1339.     CWnd parent;
  1340.     parent.Attach(hParent);
  1341.     int nType = (int)dwType;
  1342.  
  1343.     if (nType == TYPE_POP && !bAllowBoth)
  1344.     {
  1345.         parent.MessageBox(szLoadString(IDS_POP3_ONLY_ONE), 
  1346.                                         szLoadString(AFX_IDS_APP_TITLE), MB_OK);
  1347.         parent.Detach();
  1348.         return FALSE;
  1349.     }
  1350.  
  1351.     CString title;
  1352.     title.LoadString(IDS_ADD_MAIL_SERVER);
  1353.     CMailServerPropertySheet addMailServer(&parent, title, NULL, TYPE_IMAP, FALSE, bAllowBoth);
  1354.     if (IDOK == addMailServer.DoModal())
  1355.     {
  1356.         PREF_SavePrefFile();
  1357.         if (nType == TYPE_POP)
  1358.         {
  1359.             SendMessage(hControl, LB_ADDSTRING, 0, 
  1360.                 (LPARAM) (LPCTSTR)addMailServer.GetMailHostName());
  1361.         }
  1362.         parent.Detach();
  1363.         return TRUE;
  1364.     }
  1365.     else
  1366.     {
  1367.         parent.Detach();
  1368.         return FALSE;
  1369.     }
  1370. }
  1371.  
  1372. STDMETHODIMP_(BOOL) CMailNewsPreferences::EditMailServer
  1373. (HWND hParent, HWND hControl, BOOL bAllowBoth, DWORD dwType)
  1374. {
  1375.     CWnd parent;
  1376.     parent.Attach(hParent);
  1377.     CString title;
  1378.     title.LoadString(IDS_MAIL_SERVER_PROPERTY);
  1379.     int nType = (int)dwType;
  1380.  
  1381.     char serverName[MSG_MAXGROUPNAMELENGTH];
  1382.     int nIndex = (int)SendMessage(hControl, LB_GETCURSEL, 0, 0);
  1383.     SendMessage(hControl, LB_GETTEXT, (WPARAM)nIndex, 
  1384.             (LPARAM)(DWORD)serverName);
  1385.  
  1386.     CMailServerPropertySheet editMailServer(&parent, title, serverName,
  1387.                                             nType, TRUE, bAllowBoth);
  1388.     if (IDOK == editMailServer.DoModal())
  1389.     {
  1390.         PREF_SavePrefFile();
  1391.         parent.Detach();
  1392.         return TRUE;
  1393.     }
  1394.     else
  1395.     {
  1396.         parent.Detach();
  1397.         return FALSE;
  1398.     }
  1399. }
  1400.  
  1401. //delete imap server
  1402. STDMETHODIMP_(BOOL) CMailNewsPreferences::DeleteMailServer
  1403. (HWND hParent, HWND hControl, DWORD dwType)
  1404. {
  1405.     CWnd parent;
  1406.     parent.Attach(hParent);
  1407.     if (IDCANCEL == parent.MessageBox(szLoadString(IDS_REMOVE_MAILHOST_CONFIRM),
  1408.                                     szLoadString(AFX_IDS_APP_TITLE), MB_OKCANCEL))
  1409.     {
  1410.         parent.Detach();
  1411.         return FALSE;
  1412.     }
  1413.  
  1414.     int nIndex = (int)SendMessage(hControl, LB_GETCURSEL, 0, 0);
  1415.     int nType = (int)dwType;
  1416.     if (nType = TYPE_IMAP)
  1417.     {
  1418.         char serverName[MSG_MAXGROUPNAMELENGTH];
  1419.  
  1420.         MSG_Master* pMaster = WFE_MSGGetMaster();
  1421.  
  1422.         SendMessage(hControl, LB_GETTEXT, (WPARAM)nIndex, 
  1423.                 (LPARAM)(DWORD)serverName);
  1424.  
  1425.         int nTotal =  MSG_GetIMAPHosts(pMaster, NULL, 0);
  1426.         if (nTotal)
  1427.         {
  1428.              MSG_IMAPHost** hImapHost = NULL;
  1429.             hImapHost = new MSG_IMAPHost* [nTotal];
  1430.             ASSERT(hImapHost != NULL);
  1431.             nTotal =  MSG_GetIMAPHosts(pMaster, hImapHost, nTotal);
  1432.             for (int i = 0; i < nTotal; i++)
  1433.             {
  1434.                 MSG_Host* pMsgHost = MSG_GetMSGHostFromIMAPHost(hImapHost[i]);
  1435.                 if (0 == lstrcmp(serverName, MSG_GetHostName(pMsgHost)))
  1436.                     MSG_DeleteIMAPHost(pMaster, hImapHost[i]);
  1437.             }
  1438.             if (hImapHost)
  1439.                 delete [] hImapHost;
  1440.         }
  1441.     }
  1442.     else
  1443.         SendMessage(hControl, LB_DELETESTRING, (WPARAM)nIndex, 0);
  1444.  
  1445.     parent.Detach();
  1446.     return TRUE;
  1447. }
  1448.  
  1449. STDMETHODIMP CMailNewsPreferences::FillLdapDirList(HWND hControl, LPOLESTR lpServerName)
  1450. {
  1451.     if (0 == XP_ListCount(m_pLdapServers))
  1452.         return NOERROR;
  1453.     
  1454.     DIR_Server* pServer;
  1455.     //Keep m_pLdapServers, XP_ListNextObject will reset pointer
  1456.     XP_List    *pList = m_pLdapServers;
  1457.     int nSelectedIndex = 0;
  1458.     while (pServer = (DIR_Server*)XP_ListNextObject(pList))
  1459.     {
  1460.         if (pServer->description && pServer->dirType == LDAPDirectory)
  1461.         {    
  1462.             int nIndex = (int)SendMessage(hControl, CB_ADDSTRING, 0, 
  1463.                                           (LPARAM)(LPCTSTR)pServer->description);
  1464.             if (nIndex >= 0)
  1465.             {
  1466.                 SendMessage(hControl, CB_SETITEMDATA, (WPARAM)nIndex, 
  1467.                             (LPARAM)(DWORD)pServer);
  1468.                 if (DIR_TestFlag(pServer, DIR_AUTO_COMPLETE_ENABLED))
  1469.                     nSelectedIndex = nIndex;
  1470.             }
  1471.         }    
  1472.     }    
  1473.     SendMessage(hControl, CB_SETCURSEL, nSelectedIndex, 0);
  1474.     return NOERROR;
  1475. }
  1476.  
  1477. STDMETHODIMP CMailNewsPreferences::SetLdapDirAutoComplete(HWND hControl, BOOL bOnOrOff)
  1478. {
  1479.     int nIndex = (int)SendMessage(hControl, CB_GETCURSEL, 0,0);
  1480.     DIR_Server* pServer = (DIR_Server*)SendMessage(hControl, CB_GETITEMDATA, 
  1481.                                         (WPARAM)nIndex, 0);
  1482.     DIR_SetAutoCompleteEnabled(m_pLdapServers, pServer, bOnOrOff);
  1483.  
  1484.     return NOERROR;
  1485. }
  1486. #endif /* MOZ_MAIL_NEWS */
  1487.  
  1488. #ifdef MOZ_OFFLINE
  1489. /////////////////////////////////////////////////////////////////////////////
  1490. // COfflinePreference
  1491.  
  1492. class COfflinePreference : public IOfflineInterface {
  1493.     public:
  1494.         COfflinePreference();
  1495.  
  1496.         // IUnknown methods
  1497.         STDMETHODIMP QueryInterface(REFIID riid, LPVOID FAR* ppvObj);
  1498.         STDMETHODIMP_(ULONG) AddRef();
  1499.         STDMETHODIMP_(ULONG) Release();
  1500.         
  1501.         // IIntlFont methods
  1502.         STDMETHODIMP DoSelectDiscussion(HWND hParent);
  1503.  
  1504.         // Initialization routine to create contained and aggregated objects
  1505.         HRESULT         Init();
  1506.  
  1507.     private:
  1508.  
  1509.         ULONG      m_uRef;
  1510.         LPUNKNOWN m_pCategory;  // inner object supporting ISpecifyPropertyPageObjects
  1511. };
  1512.  
  1513. /////////////////////////////////////////////////////////////////////////////
  1514. // COfflinePreference
  1515.  
  1516. COfflinePreference::COfflinePreference()
  1517. {
  1518.     m_uRef = 0;
  1519.     m_pCategory = NULL;
  1520. }
  1521.  
  1522. HRESULT
  1523. COfflinePreference::Init()
  1524. {
  1525.     // Create the object as part of an aggregate
  1526.     return CoCreateInstance(CLSID_OfflinePrefs, (LPUNKNOWN)this,
  1527.         CLSCTX_INPROC_SERVER, IID_IUnknown, (LPVOID *)&m_pCategory);
  1528. }
  1529.  
  1530. STDMETHODIMP
  1531. COfflinePreference::QueryInterface(REFIID riid, LPVOID FAR* ppvObj)
  1532. {
  1533.     *ppvObj = NULL;
  1534.  
  1535.     if (riid == IID_IUnknown || riid == IID_OfflineInterface) {
  1536.         *ppvObj = (LPVOID)this;
  1537.         AddRef();
  1538.         return NOERROR;
  1539.  
  1540.     } else if (riid == IID_ISpecifyPropertyPageObjects) {
  1541.         assert(m_pCategory);
  1542.         return m_pCategory->QueryInterface(riid, ppvObj);
  1543.     }
  1544.  
  1545.     return ResultFromScode(E_NOINTERFACE);
  1546. }
  1547.  
  1548. STDMETHODIMP_(ULONG)
  1549. COfflinePreference::AddRef()
  1550. {
  1551.     return ++m_uRef;
  1552. }
  1553.  
  1554. STDMETHODIMP_(ULONG)
  1555. COfflinePreference::Release()
  1556. {
  1557.     if (--m_uRef == 0) {
  1558.         if (m_pCategory)
  1559.             m_pCategory->Release();
  1560.         delete this;
  1561.         return 0;
  1562.     }
  1563.  
  1564.     return m_uRef;
  1565. }
  1566.  
  1567. STDMETHODIMP
  1568. COfflinePreference::DoSelectDiscussion(HWND hParent)
  1569. {
  1570.     CWnd parent;
  1571.  
  1572.     parent.Attach(hParent);
  1573.  
  1574.     CDlgSelectGroups selDiscussionDlg(&parent);
  1575.     selDiscussionDlg.DoModal();
  1576.  
  1577.     parent.Detach();
  1578.     return NOERROR;
  1579. }
  1580. #endif // MOZ_OFFLINE
  1581.  
  1582. #ifdef MOZ_MAIL_NEWS
  1583. static BOOL
  1584. CreateMailNewsCategory(LPSPECIFYPROPERTYPAGEOBJECTS *pCategory)
  1585. {
  1586.     BOOL    bResult = FALSE;
  1587.  
  1588.     // Create the property page providers
  1589.     CMailNewsPreferences *pMailNews = new CMailNewsPreferences;
  1590.     pMailNews->AddRef();
  1591.  
  1592.     // Initialize the mail news object. This allows it to load any objects that are
  1593.     // contained or aggregated
  1594.     if (SUCCEEDED(pMailNews->Init())) {
  1595.         // Get the interface pointer for ISpecifyPropertyPageObjects
  1596.         if (SUCCEEDED(pMailNews->QueryInterface(IID_ISpecifyPropertyPageObjects, (LPVOID *)pCategory)))
  1597.             bResult = TRUE;
  1598.     }
  1599.     
  1600.     // We're all done with the object
  1601.     pMailNews->Release();
  1602.     return bResult;
  1603. }
  1604. #endif /* MOZ_MAIL_NEWS */
  1605.  
  1606.  
  1607. #ifdef MOZ_LOC_INDEP
  1608. /////////////////////////////////////////////////////////////////////////////
  1609. // CLIPreference
  1610.  
  1611. class CLIPreference : public ILIPrefs {
  1612.     public:
  1613.         CLIPreference();
  1614.  
  1615.         // IUnknown methods
  1616.         STDMETHODIMP QueryInterface(REFIID riid, LPVOID FAR* ppvObj);
  1617.         STDMETHODIMP_(ULONG) AddRef();
  1618.         STDMETHODIMP_(ULONG) Release();
  1619.         
  1620.         // Initialization routine to create contained and aggregated objects
  1621.         HRESULT         Init();
  1622.  
  1623.     private:
  1624.  
  1625.         ULONG      m_uRef;
  1626.         LPUNKNOWN m_pCategory;  // inner object supporting ISpecifyPropertyPageObjects
  1627. };
  1628.  
  1629. /////////////////////////////////////////////////////////////////////////////
  1630. // CLIPreference
  1631.  
  1632. CLIPreference::CLIPreference()
  1633. {
  1634.     m_uRef = 0;
  1635.     m_pCategory = NULL;
  1636. }
  1637.  
  1638. HRESULT
  1639. CLIPreference::Init()
  1640. {
  1641.     // Create the object as part of an aggregate
  1642.     return CoCreateInstance(CLSID_LIPrefs, (LPUNKNOWN)this,
  1643.         CLSCTX_INPROC_SERVER, IID_IUnknown, (LPVOID *)&m_pCategory);
  1644. }
  1645.  
  1646. STDMETHODIMP
  1647. CLIPreference::QueryInterface(REFIID riid, LPVOID FAR* ppvObj)
  1648. {
  1649.     *ppvObj = NULL;
  1650.  
  1651.     if (riid == IID_IUnknown || riid == IID_ILIlogin) {
  1652.         *ppvObj = (LPVOID)this;
  1653.         AddRef();
  1654.         return NOERROR;
  1655.  
  1656.     } else if (riid == IID_ISpecifyPropertyPageObjects) {
  1657.         assert(m_pCategory);
  1658.         return m_pCategory->QueryInterface(riid, ppvObj);
  1659.     }
  1660.  
  1661.     return ResultFromScode(E_NOINTERFACE);
  1662. }
  1663.  
  1664. STDMETHODIMP_(ULONG)
  1665. CLIPreference::AddRef()
  1666. {
  1667.     return ++m_uRef;
  1668. }
  1669.  
  1670. STDMETHODIMP_(ULONG)
  1671. CLIPreference::Release()
  1672. {
  1673.     if (--m_uRef == 0) {
  1674.         if (m_pCategory)
  1675.             m_pCategory->Release();
  1676.         delete this;
  1677.         return 0;
  1678.     }
  1679.  
  1680.     return m_uRef;
  1681. }
  1682. #endif /* MOZ_LOC_INDEP */
  1683.  
  1684.  
  1685. static void
  1686. ReloadAllWindows()
  1687. {
  1688.     for (CGenericFrame *f = theApp.m_pFrameList; f; f = f->m_pNext) {
  1689.         CWinCX *pContext = f->GetMainWinContext();
  1690.  
  1691.         if (pContext && pContext->GetContext()) {
  1692. #ifdef EDITOR 
  1693.             if (EDT_IS_EDITOR(pContext->GetContext())) {
  1694.                 // Edit can relayout page without having to do NET_GetURL
  1695.                 EDT_RefreshLayout(pContext->GetContext());
  1696.  
  1697.             } else 
  1698. #endif // EDITOR
  1699.             {
  1700.                 pContext->NiceReload();
  1701.             }
  1702.         }
  1703.     }
  1704. }
  1705.  
  1706. static BOOL
  1707. CreateAppearancesCategory(int nCharsetId, LPSPECIFYPROPERTYPAGEOBJECTS *pCategory)
  1708. {
  1709.     CAppearancePrefs   *pAppearance = new CAppearancePrefs(nCharsetId);
  1710.     BOOL                   bResult = FALSE;
  1711.     
  1712.     pAppearance->AddRef();
  1713.  
  1714.     // Initialize the appearances object. This allows it to load any objects that are
  1715.     // contained or aggregated
  1716.     if (SUCCEEDED(pAppearance->Init())) {
  1717.         // Get the interface pointer for ISpecifyPropertyPageObjects
  1718.         if (SUCCEEDED(pAppearance->QueryInterface(IID_ISpecifyPropertyPageObjects, (LPVOID *)pCategory)))
  1719.             bResult = TRUE;
  1720.     }
  1721.  
  1722.     // We're all done with the object
  1723.     pAppearance->Release();
  1724.     return bResult;
  1725. }
  1726.  
  1727. static BOOL
  1728. CreateBrowserCategory(MWContext *pContext, LPSPECIFYPROPERTYPAGEOBJECTS *pCategory)
  1729. {
  1730.     CBrowserPrefs *pBrowser;
  1731.     History_entry *pEntry;
  1732.     BOOL           bResult = FALSE;
  1733.  
  1734.     // If this is the browser then use the URL for the current page
  1735.     pEntry = pContext->type == MWContextBrowser ? pContext->hist.cur_doc_ptr : NULL;
  1736.     pBrowser = new CBrowserPrefs(pEntry ? pEntry->address : NULL);
  1737.     pBrowser->AddRef();
  1738.     
  1739.     // Initialize the browser pref object. This allows it to load any objects that are
  1740.     // contained or aggregated
  1741.     if (SUCCEEDED(pBrowser->Init())) {
  1742.         // Get the interface pointer for ISpecifyPropertyPageObjects
  1743.         if (SUCCEEDED(pBrowser->QueryInterface(IID_ISpecifyPropertyPageObjects, (LPVOID *)pCategory)))
  1744.             bResult = TRUE;
  1745.     }
  1746.  
  1747.     // We're all done with the object
  1748.     pBrowser->Release();
  1749.     return bResult;
  1750. }
  1751.  
  1752.  
  1753. #ifdef MOZ_OFFLINE        
  1754. static BOOL
  1755. CreateOfflineCategory(LPSPECIFYPROPERTYPAGEOBJECTS *pCategory)
  1756. {
  1757.     BOOL    bResult = FALSE;
  1758.         
  1759.     // Create the property page providers
  1760.     COfflinePreference *pOffline = new COfflinePreference;
  1761.     pOffline->AddRef();
  1762.  
  1763.     // Initialize the offline object. This allows it to load any objects that are
  1764.     // contained or aggregated
  1765.     if (SUCCEEDED(pOffline->Init())) {
  1766.         // Get the interface pointer for ISpecifyPropertyPageObjects
  1767.         if (SUCCEEDED(pOffline->QueryInterface(IID_ISpecifyPropertyPageObjects, (LPVOID *)pCategory)))
  1768.             bResult = TRUE;
  1769.     }
  1770.     
  1771.     // We're all done with the object
  1772.     pOffline->Release();
  1773.     return bResult;
  1774. }
  1775. #endif /* MOZ_OFFLINE */
  1776.  
  1777.  
  1778. #ifdef MOZ_LOC_INDEP
  1779. static BOOL
  1780. CreateLICategory(LPSPECIFYPROPERTYPAGEOBJECTS *pCategory)
  1781. {
  1782.     BOOL    bResult = FALSE;
  1783.         
  1784.     // Create the property page providers
  1785.     CLIPreference *pLI = new CLIPreference;
  1786.     pLI->AddRef();
  1787.  
  1788.     // Initialize the offline object. This allows it to load any objects that are
  1789.     // contained or aggregated
  1790.     if (SUCCEEDED(pLI->Init())) {
  1791.         // Get the interface pointer for ISpecifyPropertyPageObjects
  1792.         if (SUCCEEDED(pLI->QueryInterface(IID_ISpecifyPropertyPageObjects, (LPVOID *)pCategory)))
  1793.             bResult = TRUE;
  1794.     }
  1795.     
  1796.     // We're all done with the object
  1797.     pLI->Release();
  1798.     return bResult;
  1799. }
  1800. #endif // MOZ_LOC_INDEP
  1801.  
  1802. typedef HRESULT (STDAPICALLTYPE *PFNPREFS)(HWND, int, int, LPCSTR, ULONG, LPSPECIFYPROPERTYPAGEOBJECTS *, ULONG, NETHELPFUNC);
  1803.  
  1804. // Callback for prefs to display a NetHelp window
  1805. void CALLBACK
  1806. #ifndef _WIN32
  1807. __export
  1808. #endif
  1809. NetHelpWrapper(LPCSTR lpszHelpTopic)
  1810. {
  1811.     // Call internal NetHelp routine
  1812.     NetHelp(lpszHelpTopic);
  1813. }
  1814.  
  1815. void
  1816. wfe_DisplayPreferences(CGenericFrame *pFrame)
  1817. {
  1818.     HINSTANCE                         hPrefDll;
  1819.     LPSPECIFYPROPERTYPAGEOBJECTS    categories[6];
  1820.     PFNPREFS                         pfnCreatePropertyFrame;
  1821.     ULONG                             nCategories = 0;
  1822.     ULONG                             nInitialCategory;
  1823.     MWContext                         *pContext = pFrame->GetMainContext()->GetContext();
  1824.     static CGenericFrame           *pCurrentFrame = NULL;
  1825.  
  1826.     // We only allow one pref UI window up at a time
  1827.     if (pCurrentFrame) {
  1828.         HWND    hwnd = ::GetLastActivePopup(pCurrentFrame->m_hWnd);
  1829.  
  1830. #ifdef _WIN32
  1831.         ::SetForegroundWindow(hwnd);
  1832. #else
  1833.         ::BringWindowToTop(hwnd);
  1834. #endif
  1835.         return;
  1836.     }
  1837.  
  1838.     // Load the preferences UI DLL
  1839. #ifdef _WIN32
  1840.     hPrefDll = LoadLibrary("prefui32.dll");
  1841.     if (hPrefDll) {
  1842. #else
  1843.     hPrefDll = LoadLibrary("prefui16.dll");
  1844.     if ((UINT)hPrefDll > 32) {
  1845. #endif
  1846.  
  1847.         // Get the address of the routine to create the property frame
  1848.         pfnCreatePropertyFrame = (PFNPREFS)GetProcAddress(hPrefDll, "NS_CreatePropertyFrame");
  1849.         if (!pfnCreatePropertyFrame) {
  1850. #ifdef _DEBUG
  1851.             pFrame->MessageBox("Unable to get proc address for NS_CreatePropertyFrame",
  1852.                 NULL, MB_OK | MB_ICONEXCLAMATION);
  1853. #endif
  1854.             FreeLibrary(hPrefDll);
  1855.             return;
  1856.         }
  1857.         
  1858.         // Remember that this window is displaying the pref UI
  1859.         pCurrentFrame = pFrame;
  1860.  
  1861.         // Appearances category
  1862.         if (CreateAppearancesCategory(theApp.m_pIntlFont->DocCSIDtoID(pFrame->m_iCSID), &categories[nCategories]))
  1863.             nCategories++;
  1864.  
  1865.         // Browser category
  1866.         if (CreateBrowserCategory(pContext, &categories[nCategories]))
  1867.             nCategories++;
  1868.  
  1869. #ifdef MOZ_MAIL_NEWS
  1870.         // Mail and News category
  1871.         if (CreateMailNewsCategory(&categories[nCategories]))
  1872.             nCategories++;
  1873. #endif // MOZ_MAIL_NEWS
  1874.  
  1875. #ifdef MOZ_LOC_INDEP
  1876.         // LI category
  1877.         if (CreateLICategory(&categories[nCategories]))
  1878.             nCategories++;
  1879. #endif // MOZ_LOC_INDEP        
  1880.  
  1881. #ifdef EDITOR        
  1882.         // Editor category
  1883.         if (SUCCEEDED(CoCreateInstance(CLSID_EditorPrefs,
  1884.                                        NULL,
  1885.                                        CLSCTX_INPROC_SERVER,
  1886.                                        IID_ISpecifyPropertyPageObjects,
  1887.                                        (LPVOID *)&categories[nCategories]))) {
  1888.             nCategories++;
  1889.         }
  1890. #endif EDITOR
  1891.  
  1892. #ifdef MOZ_OFFLINE
  1893.         // Offline category
  1894.         if (CreateOfflineCategory(&categories[nCategories]))
  1895.             nCategories++;
  1896. #endif // MOZ_OFFLINE        
  1897.  
  1898.         // Advanced category
  1899.         if (SUCCEEDED(CoCreateInstance(CLSID_AdvancedPrefs,
  1900.                                        NULL,
  1901.                                        CLSCTX_INPROC_SERVER,
  1902.                                        IID_ISpecifyPropertyPageObjects,
  1903.                                        (LPVOID *)&categories[nCategories]))) {
  1904.             nCategories++;
  1905.         }
  1906.  
  1907.         // Make sure we have at least one category
  1908.         if (nCategories == 0) {
  1909.             pFrame->MessageBox(szLoadString(IDS_CANT_LOAD_PREFS), NULL, MB_OK | MB_ICONEXCLAMATION);
  1910.             FreeLibrary(hPrefDll);
  1911.             return;
  1912.         }
  1913.         
  1914.         // Hack to indicate whether we need to reload the windows because something
  1915.         // like a color or a font changed
  1916.         //
  1917.         // We do have code that observes the XP prefs, but if more than one preference
  1918.         // changes we'll get several callbacks (we don't have a way to do batch changes)
  1919.         // and we'll reload the windows multiple times which is very sloppy...
  1920.         g_bReloadAllWindows = FALSE;
  1921.  
  1922.         // Figure out what the initial category we display should be
  1923.         if (pFrame->IsEditFrame()) {
  1924.             nInitialCategory = 3;
  1925.  
  1926.         } else if (pContext->type == MWContextMail ||
  1927.                  pContext->type == MWContextMailMsg ||
  1928.                  pContext->type == MWContextMessageComposition ||
  1929.                  pContext->type == MWContextAddressBook) {
  1930.             nInitialCategory = 2;
  1931.  
  1932.         } else {
  1933.             nInitialCategory = 1;
  1934.         }
  1935.         
  1936.         // Display the preferences
  1937.         pfnCreatePropertyFrame(pFrame->m_hWnd, -1, -1, "Preferences", nCategories, categories,
  1938.             nInitialCategory, NetHelpWrapper);
  1939.         pCurrentFrame = NULL;
  1940.  
  1941.         // Release the interface pointers for the preference categories
  1942.         for (ULONG i = 0; i < nCategories; i++)
  1943.             categories[i]->Release();
  1944.  
  1945.         // Unload the library
  1946.         FreeLibrary(hPrefDll);
  1947.  
  1948.         // See if we need to reload the windows
  1949.         if (g_bReloadAllWindows) {
  1950.             ReloadAllWindows();
  1951.             g_bReloadAllWindows = FALSE;
  1952.         }
  1953.  
  1954.         // Save out the preferences
  1955.         PREF_SavePrefFile();
  1956.  
  1957.     } else {
  1958. #ifdef _DEBUG
  1959.         MessageBox(NULL, "Unable to load NSPREFUI.DLL", "Navigator",
  1960.             MB_OK | MB_ICONEXCLAMATION);
  1961. #endif
  1962.     }
  1963. }
  1964.  
  1965.