home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / macfe / prefs / CPrefsMediator.cp < prev    next >
Encoding:
Text File  |  1998-04-08  |  25.3 KB  |  771 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 "CPrefsMediator.h"
  20.  
  21. #include "prefapi.h"
  22.  
  23. #include "macutil.h"
  24. #include "ufilemgr.h"
  25.  
  26. #include "MPreference.h"
  27. #include "CSizePopup.h"
  28. #ifdef MOZ_MAIL_NEWS
  29. #include "CMessageFolder.h"
  30. #endif
  31. #include "StSetBroadcasting.h"
  32. #include "InternetConfig.h"
  33. #include "CMouseDragger.h"
  34.  
  35. Boolean    CPrefsMediator::sUseIC = false;
  36. LView *CPrefsMediator::sPanel = nil;
  37. LWindow    *CPrefsMediator::sWindow = nil;
  38. CPrefsDialog::Selection_T CPrefsMediator::sInitialSelection
  39.     = CPrefsDialog::eIgnore;
  40.  
  41. #pragma mark ---CControlExtension---
  42. //======================================
  43. class CControlExtension: LCaption
  44. //======================================
  45. {
  46.     public:
  47.  
  48.         enum
  49.         {
  50.             class_ID = 'CtlX'
  51.         };
  52.  
  53.                         CControlExtension(LStream *inStream);
  54.         virtual            ~CControlExtension() {}
  55.  
  56.         virtual void    ClickSelf(const SMouseDownEvent& inMouseDown);
  57.  
  58.         virtual    void    FinishCreateSelf();
  59.  
  60.     protected:
  61.         PaneIDT            mControlID;
  62.         LControl        *mControl;
  63. }; // class CControlExtension
  64.  
  65. //----------------------------------------------------------------------------------------
  66. CControlExtension::CControlExtension(LStream *inStream):
  67.     LCaption(inStream),
  68.     mControl(nil)
  69. //----------------------------------------------------------------------------------------
  70. {
  71.     *inStream >> mControlID;
  72. } // CControlExtension::CControlExtension
  73.  
  74. //----------------------------------------------------------------------------------------
  75. void CControlExtension::FinishCreateSelf()
  76. //----------------------------------------------------------------------------------------
  77. {
  78.     LPane    *pane = this;
  79.     LView    *superView, *topView = nil;
  80.     #pragma warn_possunwant off
  81.     while (superView = pane->GetSuperView())
  82.     #pragma warn_possunwant reset
  83.     {
  84.         topView = superView;
  85.         pane = superView;
  86.     }
  87.     XP_ASSERT(topView);
  88.     if (topView)
  89.     {
  90.         mControl = (LControl *)topView->FindPaneByID(mControlID);
  91.     }
  92.     XP_ASSERT(mControl);
  93. } // CControlExtension::FinishCreateSelf
  94.  
  95. //----------------------------------------------------------------------------------------
  96. void CControlExtension::ClickSelf(const SMouseDownEvent& /*inMouseDown*/)
  97. //----------------------------------------------------------------------------------------
  98. {
  99.     if (mControl)
  100.         mControl->SimulateHotSpotClick(1);    // any value > 0 && < 128 should work
  101. } // CControlExtension::ClickSelf
  102.  
  103. #if 0
  104.  
  105. #pragma mark ---class CControlExtensionAttachment---
  106. //======================================
  107. class CControlExtensionAttachment: LAttachment
  108. //======================================
  109. {
  110.     public:
  111.         CControlExtensionAttachment(LControl *targetControl);
  112.         virtual    ~CControlExtensionAttachment() {}
  113.  
  114.     protected:
  115.         LControl        *mControl;
  116.  
  117.         virtual void    ExecuteSelf(MessageT inMessage, void *ioParam);
  118. }; // class CControlExtensionAttachment
  119.  
  120. //----------------------------------------------------------------------------------------
  121. CControlExtensionAttachment::CControlExtensionAttachment(LControl* targetControl)
  122. //----------------------------------------------------------------------------------------
  123. :    LAttachment(msg_Click, true)
  124. ,    mControl(targetControl)
  125. {
  126. }
  127.  
  128. //----------------------------------------------------------------------------------------
  129. void CControlExtensionAttachment::ExecuteSelf(MessageT inMessage, void* ioParam)
  130. //----------------------------------------------------------------------------------------
  131. {
  132.     if (mControl)
  133.         mControl->SimulateHotSpotClick(1);    // any value > 0 && < 128 should work
  134. }
  135. #endif    // 0
  136.  
  137. #ifdef MOZ_MAIL_NEWS
  138. #pragma mark ---CPopupFolderMenu---
  139.  
  140. //======================================
  141. class CPopupFolderMenu : public LGAPopup, public CGAPopupFolderMixin
  142. //======================================
  143. {
  144.     public:
  145.         enum
  146.         {
  147.             class_ID = 'PupF'
  148.         };
  149.  
  150.                         CPopupFolderMenu(LStream    *inStream);
  151.     virtual                ~CPopupFolderMenu();
  152.     virtual void        FinishCreateSelf();
  153.     virtual    Boolean        FolderFilter(const CMessageFolder &folder);
  154.  
  155. //    private:
  156. // It turns out that this causes a crash in some thread code. Apparently someone
  157. // is counting on the MSG_Master not going away
  158. //        CMailNewsContext    mMailNewsContext;
  159.             // OK, what the heck is this for? Well the CPopupFolderMenus that we
  160.             // create will call CMailFolderMixin::UpdateMailFolderMixinsNow() in
  161.             // FinishCreateSelf(). This call will call CMailNewsContext::GetMailMaster().
  162.             // CMailNewsContext::GetMailMaster() will  create a MSG_Master if the static
  163.             // MSG_Master does not already exist. This means that the code would work
  164.             // without mMailNewsContext, but the static MSG_Master would continue to exist
  165.             // after we are finished. This is not good if the user is not using mail. So
  166.             // we create a CMailNewsContext because its contrustor will create the
  167.             // the static MSG_Master but it is ref counted and destroyed in
  168.             // CMailNewsContext::~CMailNewsContext.
  169. }; // class CPopupFolderMenu
  170.  
  171. //----------------------------------------------------------------------------------------
  172. CPopupFolderMenu::CPopupFolderMenu(LStream    *inStream)
  173. //----------------------------------------------------------------------------------------
  174. :    LGAPopup(inStream)
  175. {
  176.     mDesiredFolderFlags = eWantPOP;
  177. }
  178.  
  179. //----------------------------------------------------------------------------------------
  180. CPopupFolderMenu::~CPopupFolderMenu()
  181. //----------------------------------------------------------------------------------------
  182. {
  183. }
  184.  
  185. //----------------------------------------------------------------------------------------
  186. void CPopupFolderMenu::FinishCreateSelf()
  187. //----------------------------------------------------------------------------------------
  188. {
  189.     LGAPopup::FinishCreateSelf();
  190.     CMailFolderMixin::UpdateMailFolderMixinsNow(this);
  191. }
  192.  
  193. //----------------------------------------------------------------------------------------
  194. Boolean CPopupFolderMenu::FolderFilter(const CMessageFolder& folder)
  195. //----------------------------------------------------------------------------------------
  196. {
  197.     Boolean    result = CGAPopupFolderMixin::FolderFilter(folder);
  198.     // We want to exclude the Outbox.
  199.     if (result && (folder.GetFolderFlags() & MSG_FOLDER_FLAG_QUEUE))
  200.     {
  201.         result = false;
  202.     }
  203.     return result;
  204. }
  205. #endif // MOZ_MAIL_NEWS
  206.  
  207. #pragma mark ---CPrefsMediator---
  208.  
  209. //----------------------------------------------------------------------------------------
  210. CPrefsMediator::CPrefsMediator(PaneIDT inMainPaneID)
  211. //----------------------------------------------------------------------------------------
  212. :    mMainPane(nil)
  213. ,    mNeedsPrefs(true)
  214. ,    mMainPaneID(inMainPaneID)
  215. ,    mLatentSub(nil)
  216. {
  217.     MPreferenceBase::SetWriteOnDestroy(false);
  218. }
  219.  
  220. //----------------------------------------------------------------------------------------
  221. CPrefsMediator::~CPrefsMediator()
  222. //----------------------------------------------------------------------------------------
  223. {
  224. }
  225.  
  226. //----------------------------------------------------------------------------------------
  227. void CPrefsMediator::LoadPrefs()
  228. //----------------------------------------------------------------------------------------
  229. {
  230. }
  231.  
  232. //----------------------------------------------------------------------------------------
  233. void CPrefsMediator::WritePrefs()
  234. //----------------------------------------------------------------------------------------
  235. {
  236. }
  237.  
  238. //----------------------------------------------------------------------------------------
  239. void CPrefsMediator::StepAside()
  240. //----------------------------------------------------------------------------------------
  241. {
  242.     if (mMainPane)
  243.     {
  244.         mLatentSub = LCommander::GetTarget();
  245.         SwitchTarget(nil); // take current chain off duty, so that SetLatentSub() can work.
  246.         mMainPane->Hide();
  247.     }
  248. }
  249.  
  250. //----------------------------------------------------------------------------------------
  251. void CPrefsMediator::LoadPanes()
  252. //----------------------------------------------------------------------------------------
  253. {
  254.     if (!mMainPane)
  255.         LoadMainPane();
  256.     mMainPane->Hide();    // this is needed for IC support
  257.                         // when panes are loaded, but not immediately displayed
  258.     if (mNeedsPrefs)
  259.     {
  260.         LoadPrefs();
  261.         mNeedsPrefs = false;
  262.     }
  263.     UpdateFromIC();
  264. }
  265.  
  266. //----------------------------------------------------------------------------------------
  267. void CPrefsMediator::StepForward(LCommander *defaultSub)
  268. //----------------------------------------------------------------------------------------
  269. {
  270.     TrySetCursor(watchCursor);
  271.     Boolean firstTime = (mMainPane == nil);
  272.     if (!firstTime && mLatentSub != sWindow)
  273.         sWindow->SetLatentSub(mLatentSub);    // restore latent sub from previously hidden pane.
  274.                                             // In the first-time case,  it's done in FinishCreate().
  275.     LoadPanes();
  276.     if (mMainPane)
  277.     {
  278.         mMainPane->Show();
  279.         mLatentSub = sWindow->GetLatentSub();
  280.         if (!mLatentSub)
  281.             mLatentSub = defaultSub;
  282.         SwitchTarget(mLatentSub);
  283.     }
  284. //    if (firstTime)
  285. //        SelectFirstEnabledEditField();        // On subsequent times, use the user's selection?
  286.             // Actually, don't do this.  The edittext pref resources all stand up and say which
  287.             // one wants to be the target.
  288.     SetCursor(&qd.arrow);
  289. }
  290.  
  291. //----------------------------------------------------------------------------------------
  292. void CPrefsMediator::LoadMainPane()
  293. //----------------------------------------------------------------------------------------
  294. {
  295.     sWindow->UpdatePort();
  296.         // The previous contents have been "hidden" but they are still visible. If we
  297.         // did not call UpdatePort() then the new content would appear over the old,
  298.         // but that is OK because everything gets straightened out at the next update.
  299.         // The only problem is if a panel is slow to draw itself-- the
  300.         // Mail & News / Messages pane is a good example--then we can actually see both
  301.         // the old and the new contents at the same time. Bad thing.
  302.     PaneIDT    paneID = GetMainPaneID();
  303.     mMainPane = UReanimator::CreateView(paneID, sPanel, sWindow);
  304.     UReanimator::LinkListenerToControls(this, mMainPane, paneID);
  305. }
  306.  
  307. //----------------------------------------------------------------------------------------
  308. void CPrefsMediator::Canceled()
  309. //----------------------------------------------------------------------------------------
  310. {
  311.     mNeedsPrefs = true;
  312.     MPreferenceBase::SetWriteOnDestroy(false);
  313. }
  314.  
  315. //----------------------------------------------------------------------------------------
  316. void CPrefsMediator::ListenToMessage(MessageT inMessage, void */*ioParam*/)
  317. //----------------------------------------------------------------------------------------
  318. {
  319.     switch (inMessage)
  320.     {
  321.         case eCommitPrefs:
  322.             WritePrefs();
  323.             MPreferenceBase::SetWriteOnDestroy(true);
  324.             break;
  325.         case eCancelPrefs:
  326.             Canceled();
  327.             break;
  328.         default:
  329.             break;
  330.     }
  331. }
  332.  
  333. //----------------------------------------------------------------------------------------
  334. MPreferenceBase* CPrefsMediator::GetPreferenceObject(PaneIDT inPaneID) const
  335. //----------------------------------------------------------------------------------------
  336. {
  337.     LPane* p = FindPaneByID(inPaneID);
  338.     MPreferenceBase* pb = dynamic_cast<MPreferenceBase*>(p);
  339.     SignalIf_(!pb);
  340.     return pb;
  341. }
  342.  
  343. //----------------------------------------------------------------------------------------
  344. Boolean CPrefsMediator::PaneHasLockedPref(PaneIDT inPaneID) const
  345. //----------------------------------------------------------------------------------------
  346. {
  347.     MPreferenceBase* pb = GetPreferenceObject(inPaneID);
  348.     if (pb)
  349.         return pb->IsLocked();
  350.     return true;
  351. }
  352.  
  353. //----------------------------------------------------------------------------------------
  354. void CPrefsMediator::ReadDefaultPref(PaneIDT inPaneID)
  355. //----------------------------------------------------------------------------------------
  356. {
  357.     MPreferenceBase* pb = GetPreferenceObject(inPaneID);
  358.     if (pb)
  359.         pb->ReadDefaultSelf();
  360. }
  361.  
  362. //----------------------------------------------------------------------------------------
  363. void CPrefsMediator::ChangePrefName(PaneIDT inPaneID, const char* inNewName)
  364. //----------------------------------------------------------------------------------------
  365. {
  366.     MPreferenceBase::ChangePrefName(mMainPane, inPaneID, inNewName);
  367. }
  368.  
  369. //----------------------------------------------------------------------------------------
  370. void CPrefsMediator::SetValidationFunction(
  371.     PaneIDT inPaneID,
  372.     CValidEditField::ValidationFunc inFunc) const
  373. //----------------------------------------------------------------------------------------
  374. {
  375.     CValidEditField* p =
  376.         (CValidEditField*)FindPaneByID(inPaneID);
  377.     p = dynamic_cast<CValidEditField*>(p);
  378.     Assert_(p); // only makes sense for CValidEditField.
  379.     if (p)
  380.         p->SetValidationFunction(inFunc);
  381. }
  382.  
  383. // static
  384. //----------------------------------------------------------------------------------------
  385. Boolean CPrefsMediator::CanSwitch(LCommander *inNewTarget)
  386. //----------------------------------------------------------------------------------------
  387. {
  388.     CValidEditField    *target = dynamic_cast<CValidEditField    *>(LCommander::GetTarget());
  389.     if (target)
  390.         return target->AllowTargetSwitch(inNewTarget);
  391.     return true;
  392. }
  393.  
  394.  
  395. //----------------------------------------------------------------------------------------
  396. // static
  397. void CPrefsMediator::SelectFirstEnabledEditField()
  398. //----------------------------------------------------------------------------------------
  399. {
  400.     LEditField *currentTarget = dynamic_cast<LEditField *>(LCommander::GetTarget());
  401.     if (currentTarget)
  402.     {
  403.         if (!currentTarget->IsEnabled())
  404.         {
  405.             LTabGroup *tabGroup =
  406.                     dynamic_cast<LTabGroup *>(currentTarget->GetSuperCommander());
  407.             if (tabGroup)
  408.             {
  409.                 tabGroup->RotateTarget(false /*not backward*/);
  410.                 LEditField    *oldTarget = currentTarget;
  411.                 currentTarget = dynamic_cast<LEditField *>(LCommander::GetTarget());
  412.                 if (currentTarget)
  413.                 {
  414.                     if (currentTarget == oldTarget)
  415.                     {
  416.                         // This means that the tab group couldn't find any edit field
  417.                         // that was not disabled. So we need to take this guy off duty.
  418.                         currentTarget->SwitchTarget(nil);
  419.                     }
  420.                 }
  421.                 // else what the heck does this mean?
  422.             }
  423.             if (currentTarget && currentTarget->IsEnabled())
  424.             {
  425.                 currentTarget->SelectAll();
  426.             }
  427.         }
  428.     }
  429. }
  430.  
  431. enum
  432. {
  433.     eNNTPStandardPort    = 119,
  434.     eNNTPSecurePort    = 563
  435. };
  436.  
  437. //----------------------------------------------------------------------------------------
  438. void CPrefsMediator::SetEditFieldsWithICPref(ConstStr255Param prefName,
  439.                                         PaneIDT editFieldID,
  440.                                         Boolean    stripPortNumber,
  441.                                         PaneIDT    portFieldID,
  442.                                         Boolean    portLocked,
  443.                                         long    /*portNumber*/)
  444.     // If stripPortNumber is false then portFieldID and portLocked are ignored.
  445.     // If stripPortNumber is true then the first colon and any chars following it are stripped.
  446.     // If portFieldID is non-zero and portLocked is false, then the port value is set.
  447. //----------------------------------------------------------------------------------------
  448. {
  449.     if (!PaneHasLockedPref(editFieldID))
  450.     {
  451.         LEditField    *editField = (LEditField *)FindPaneByID(editFieldID);
  452.         assert(editField);
  453.         if (UseIC())
  454.         {
  455.             Str255    s;
  456.             long    portNumber = eNNTPStandardPort;
  457.             long    *portNumberPtr = stripPortNumber ? &portNumber: nil;
  458.  
  459.             CInternetConfigInterface::GetInternetConfigString(prefName, s, portNumberPtr);
  460.             editField->SetDescriptor(s);
  461.             editField->Disable();
  462.             if (stripPortNumber && portFieldID && !portLocked)
  463.             {
  464.                 LEditField    *portField = (LEditField *)FindPaneByID(portFieldID);
  465.                 assert(portField);
  466.                 portField->SetValue(portNumber);
  467.                 portField->Disable();
  468.             }
  469.         }
  470.         else
  471.         {
  472.             editField->Enable();
  473.             if (stripPortNumber && portFieldID && !portLocked)
  474.             {
  475.                 LEditField    *portField = (LEditField *)FindPaneByID(portFieldID);
  476.                 assert(portField);
  477.                 portField->Enable();
  478.             }
  479.         }
  480.     }
  481. }
  482.  
  483. //----------------------------------------------------------------------------------------
  484. int CPrefsMediator::SetFontSizePopupWithIntPref(const char *prefName,
  485.                                             PaneIDT popupID,
  486.                                             Boolean &locked,
  487.                                             int defaultValue)
  488. //----------------------------------------------------------------------------------------
  489. {
  490.     int32    result = defaultValue;
  491.     int prefError = PREF_NOERROR;
  492.     CSizePopup    *thePopup = (CSizePopup *)FindPaneByID(popupID);
  493.     XP_ASSERT(thePopup);
  494.     prefError = PREF_GetIntPref(prefName, &result);
  495.     locked = PREF_PrefIsLocked(prefName);
  496.  
  497.     if (prefError == PREF_NOERROR)
  498.     {
  499.         thePopup->SetFontSize(result);
  500.     }
  501.     if (locked)
  502.     {
  503.         thePopup->Disable();
  504.     }
  505.     return result;
  506. }
  507.  
  508. #ifdef MOZ_MAIL_NEWS
  509. //----------------------------------------------------------------------------------------
  510. void CPrefsMediator::SetFolderPopupWithPref(    const char *prefName,
  511.                                             PaneIDT popupID,
  512.                                             Boolean& locked,
  513.                                             const char* /*defaultValue*/)
  514. //----------------------------------------------------------------------------------------
  515. {
  516.     CPopupFolderMenu    *thePopup =
  517.         (CPopupFolderMenu *)FindPaneByID(popupID);
  518.     XP_ASSERT(thePopup);
  519.     // XP prefs: Read alias as binary type
  520.     AliasHandle aliasH = NULL;
  521.     int size;
  522.     void* alias;
  523.     if (PREF_CopyBinaryPref(prefName, &alias, &size ) == 0)
  524.     {
  525.         PtrToHand(alias, &(Handle)aliasH, size);
  526.         XP_FREE(alias);
  527.     }
  528.  
  529.     FSSpec    target;
  530.     Boolean    wasChanged;
  531.     OSErr err = ResolveAlias(nil, aliasH, &target, &wasChanged);
  532.     DisposeHandle((Handle)aliasH);
  533.  
  534.     if (!err)
  535.     {
  536.         locked = PREF_PrefIsLocked(prefName);
  537.  
  538.         // alias to path name
  539.  
  540.         char* pathName = CFileMgr::EncodedPathNameFromFSSpec(target, true);
  541.         if (pathName && *pathName)
  542.         {
  543.             thePopup->MSetSelectedFolderName(pathName);
  544.         }
  545.         XP_FREEIF(pathName);
  546.         if (locked)
  547.         {
  548.             thePopup->Disable();
  549.         }
  550.     }
  551.     return;
  552. }
  553. #endif // MOZ_MAIL_NEWS
  554.  
  555. //----------------------------------------------------------------------------------------
  556. Boolean CPrefsMediator::SetEditFieldWithLocalFileURL(PaneIDT editFieldID, Boolean /*locked*/)
  557. //----------------------------------------------------------------------------------------
  558. {
  559.     StandardFileReply    spec;
  560.  
  561.     
  562.  
  563.     Boolean    result = CFilePicker::DoCustomGetFile(
  564.                                             spec,
  565.                                             CFilePicker::TextFiles,
  566.                                             false);
  567.     if (result)
  568.     {
  569.         char *url = CFileMgr::GetURLFromFileSpec(spec.sfFile);
  570.  
  571.         if (url)
  572.         {
  573.             LEditField    *theField = (LEditField *)FindPaneByID(editFieldID);
  574.             XP_ASSERT(theField);
  575.             LStr255    pString(url);
  576.             theField->SetDescriptor(pString);
  577.             theField->SelectAll();
  578.             XP_FREE(url);
  579.         }
  580.     }
  581.     return result;
  582. }
  583.  
  584. //----------------------------------------------------------------------------------------
  585. void CPrefsMediator::SetIntPrefWithFontSizePopup(    const char *prefName,
  586.                                                 PaneIDT popupID,
  587.                                                 Boolean locked)
  588. //----------------------------------------------------------------------------------------
  589. {
  590.     if (!locked)
  591.     {
  592.         CSizePopup *thePopup = (CSizePopup *)FindPaneByID(popupID);
  593.         XP_ASSERT(thePopup);
  594.         Int32    popupValue        = thePopup->GetFontSize();
  595.         PREF_SetIntPref(prefName, popupValue);
  596.     }
  597. }
  598.  
  599. #ifdef MOZ_MAIL_NEWS
  600. //----------------------------------------------------------------------------------------
  601. void CPrefsMediator::SetPrefWithFolderPopup(    const char *prefName,
  602.                                             PaneIDT popupID,
  603.                                             Boolean locked)
  604. //----------------------------------------------------------------------------------------
  605. {
  606.     if (!locked)
  607.     {
  608.         CPopupFolderMenu    *thePopup =
  609.             (CPopupFolderMenu *)FindPaneByID(popupID);
  610.         XP_ASSERT(thePopup);
  611.         const char* folderName = thePopup->MGetSelectedFolderName();
  612.  
  613.         // drop out if no folder is selected (b2 patch; the popups should really have
  614.         // non-empty defaults but this may also happen if folder doesn't exist anymore?)
  615.         if (!folderName || !*folderName)
  616.             return;
  617.  
  618.         // make alias
  619.         FSSpec    fileSpec;
  620.         OSErr    iErr = CFileMgr::FSSpecFromLocalUnixPath(folderName, &fileSpec);
  621.  
  622.         if (!iErr)
  623.         {
  624.             AliasHandle    aliasH;
  625.             iErr = NewAlias(nil, &fileSpec, &aliasH);
  626.             if (!iErr)
  627.             {
  628.                 Size    lByteCnt = GetHandleSize((Handle)aliasH);
  629.                 HLock((Handle)aliasH);
  630.                 PREF_SetBinaryPref(prefName, *aliasH, lByteCnt);
  631.                 DisposeHandle((Handle)aliasH);
  632.             }
  633.         }
  634.     }
  635. }
  636. #endif // MOZ_MAIL_NEWS
  637.  
  638. //----------------------------------------------------------------------------------------
  639. void CPrefsMediator::ActivateHelp( )
  640. // Called when the user clicks on the "Help" button in the Prefs window. Apart from working
  641. // out the help name from the PPob resource name, this is just a pass-through
  642. // to the appropriate FE call with the current help topic for this pane.
  643. //----------------------------------------------------------------------------------------
  644. {
  645.     // The help string is the resource name of the 'PPob' resource for the help pane.  
  646.     ::SetResLoad(false);
  647.     Handle h = ::GetResource('PPob', mMainPaneID);
  648.     if (!h)
  649.         return;
  650.     ::SetResLoad(true);
  651.     short idIgnored; ResType resTypeIgnored;
  652.     CStr255 resName;
  653.     ::GetResInfo(h, &idIgnored, &resTypeIgnored, resName);
  654.     if (!*h)
  655.         ::ReleaseResource(h); // if master pointer is not nil, it was not we who loaded it!
  656.     if (resName.Length() == 0)
  657.         return;
  658.     // The pref strings are long and redundant.  This means that the significant part
  659.     // is not visible in Constructor.  So I replaced the two common substrings "avigat" and
  660.     // "r:PREFERENCES_" with "╔" and I'm putting them back in here.  Example:
  661.     // resource name "n╔APPEARANCE" becomes help name "navigatr:PREFERENCES_APPEARANCE"
  662.     // resource name "c╔EDITOR_GENERAL" becomes help name "composer:PREFERENCES_EDITOR_GENERAL"
  663.     char fullhelpname[256];
  664.     Assert_(resName[2] == (unsigned char)'╔');
  665.     if (resName[2] != (unsigned char)'╔')
  666.         return; // No help available for this topic
  667.     switch (resName[1])
  668.     {
  669.         case 'n':
  670.             XP_STRCPY(fullhelpname, "navigat");
  671.             break;
  672.         case 'c':
  673.             XP_STRCPY(fullhelpname, "compose");
  674.             break;
  675.         case 'm':
  676.             XP_STRCPY(fullhelpname, "messeng");
  677.             break;
  678.         default:
  679.             Assert_(false);
  680.             return;
  681.     }
  682.     XP_STRCAT(fullhelpname, "r:PREFERENCES_");
  683.     XP_STRCAT(fullhelpname, 2 + (const char*)resName);
  684.     ShowHelp(fullhelpname);
  685. } // ActivateHelp
  686.  
  687. //----------------------------------------------------------------------------------------
  688. void CDragOrderTextList::MoveRow(TableIndexT inCurrRow, TableIndexT inNewRow)
  689. //----------------------------------------------------------------------------------------
  690. {
  691.     Assert_(IsValidRow(inCurrRow) && IsValidRow(inNewRow));
  692.     if (inCurrRow == inNewRow)
  693.         return;
  694.  
  695.     { // -- broadcasting scope
  696.         STableCell currCell(inCurrRow, 1);
  697.         StSetBroadcasting(this, false);
  698.         // Don't broadcast that the selection has changed, because it really hasn't
  699.         Uint32    ioDataSize;
  700.         GetCellData(currCell, nil, ioDataSize);
  701.         if (ioDataSize)
  702.         {
  703.             char *temp = (char *)XP_ALLOC(ioDataSize);
  704.             if (temp)
  705.             {
  706.                 GetCellData(currCell, temp, ioDataSize);
  707.                 RemoveRows(1, inCurrRow, false);
  708.                 InsertRows(1, inNewRow - 1, temp, ioDataSize, true);
  709.                 XP_FREE(temp);
  710.             }
  711.         }
  712.     } // -- broadcasting scope
  713.     BroadcastMessage(msg_ChangedOrder);
  714.     SelectCell(STableCell(inNewRow, 1));
  715.     Refresh();
  716. }
  717.  
  718. //----------------------------------------------------------------------------------------
  719. void CDragOrderTextList::ClickCell(    const STableCell &inCell,
  720.                             const SMouseDownEvent &inMouseDown)
  721. //----------------------------------------------------------------------------------------
  722. {
  723.     if ( LPane::GetClickCount() == 2 )
  724.     {
  725.         if (mDoubleClickMsg != msg_Nothing)
  726.         {
  727.             BroadcastMessage(mDoubleClickMsg, (void*) this);
  728.         }
  729.     }
  730.     else if (mRows > 1 && !mOrderLocked)
  731.     {
  732.         CTableRowDragger dragger(inCell.row);
  733.         
  734.         SPoint32 startMouseImagePt;
  735.         LocalToImagePoint(inMouseDown.whereLocal, startMouseImagePt);
  736.         
  737.         // Restrict dragging to a thin vertical column the height of the image
  738.         
  739.         LImageRect dragPinRect;
  740.         {
  741.             Int32 left, top, right, bottom;
  742.             GetImageCellBounds(inCell, left, top, right, bottom);
  743.             dragPinRect.Set(startMouseImagePt.h, startMouseImagePt.v - top, startMouseImagePt.h, 
  744.                             mImageSize.height - (bottom - startMouseImagePt.v) + 1);
  745.         }
  746.         TrySetCursor(eHandClosedCursorID);
  747.         dragger.DoTrackMouse(this, &startMouseImagePt, &dragPinRect, 2, 2);
  748.             
  749.         TableIndexT newRow = dragger.GetDraggedRow();
  750.             
  751.         if (newRow)
  752.         {
  753.             MoveRow(inCell.row, newRow);
  754. //            CMoveFilterAction *action = new CMoveFilterAction(this, inCell.row, newRow);
  755. //            FailNIL_(action);
  756. //            PostAction(action);
  757.         }
  758.     }
  759. } // CDragOrderTextList::ClickCell
  760.  
  761. //----------------------------------------------------------------------------------------
  762. void CPrefsMediator::RegisterViewClasses()
  763. //----------------------------------------------------------------------------------------
  764. {
  765. #ifdef MOZ_MAIL_NEWS
  766.     RegisterClass_(CPopupFolderMenu);
  767. #endif
  768.     RegisterClass_( CControlExtension);
  769.     RegisterClass_(CDragOrderTextList);
  770. }
  771.