home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / macfe / utility / PrefControls.cp < prev    next >
Encoding:
Text File  |  1998-04-08  |  13.9 KB  |  510 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 "PrefControls.h"
  20.  
  21. #include "MPreference.h"
  22. #include "CValidEditField.h"
  23.  
  24. #include "prefwutil.h"
  25. #include "prefapi.h"
  26. #include "ufilemgr.h"
  27. #include "StSetBroadcasting.h"
  28.  
  29. #include "xp_mcom.h"
  30.  
  31. #include <LGACheckbox.h>
  32. #include <LGARadioButton.h>
  33. #include <LGAPopup.h>
  34.  
  35. // Note.    We can do java-style 'inline' virtual functions here, because these classes
  36. //            all have file scope.  If you ever move these declarations to a header, you
  37. //            should non-inline 'em.
  38.  
  39. #pragma mark ---CPrefCheckbox---
  40. //======================================
  41. class CPrefCheckbox
  42. //======================================
  43. :    public LGACheckbox
  44. ,    public MPreference<LControl,XP_Bool>
  45. {
  46. public:
  47.     CPrefCheckbox(LStream* inStream)
  48.         :    LGACheckbox(inStream)
  49.         ,    MPreference<LControl,XP_Bool>(this, inStream)
  50.         {
  51.         }
  52.     virtual ~CPrefCheckbox()
  53.         {
  54.             WriteSelf();
  55.                 // checkbox always writes its pane value ^ its ordinal.
  56.                  // Thus: if mOrdinal == 1, the checkbox reverses the sense of the pref.
  57.         }
  58.     enum { class_ID = 'Pchk' };
  59.     virtual void FinishCreateSelf()
  60.         {
  61.             LGACheckbox::FinishCreateSelf();
  62.             MPreferenceBase::FinishCreate();
  63.         }
  64. }; // class CPrefCheckbox
  65.  
  66. #pragma mark ---CBoolPrefRadio---
  67. //======================================
  68. class CBoolPrefRadio
  69. // Actually, because of the writing-out policy, only the zero-ordinal radio button
  70. // needs to be a CBoolPrefRadio.  The other one can be just a LGARadioButton.
  71. //======================================
  72. :    public LGARadioButton
  73. ,    public MPreference<LControl,XP_Bool>
  74. {
  75. public:
  76.     CBoolPrefRadio(LStream* inStream)
  77.         :    LGARadioButton(inStream)
  78.         ,    MPreference<LControl,XP_Bool>(this, inStream)
  79.         {
  80.         }
  81.     virtual ~CBoolPrefRadio()
  82.         {
  83.             // Only the radio button with a zero ordinal writes its value out.
  84.             // It writes out its pane value.
  85.             if (mOrdinal == 0)
  86.                 WriteSelf();
  87.         }
  88.     enum { class_ID = 'Brad' };
  89.     virtual void FinishCreateSelf()
  90.         {
  91.             LGARadioButton::FinishCreateSelf();
  92.             MPreferenceBase::FinishCreate();
  93.         }
  94. }; // class CBoolPrefRadio
  95.  
  96. #pragma mark ---CIntPrefRadio---
  97. //======================================
  98. class CIntPrefRadio
  99. //======================================
  100. :    public LGARadioButton
  101. ,    public MPreference<LControl,int32>
  102. {
  103. public:
  104.     CIntPrefRadio(LStream* inStream)
  105.         :    LGARadioButton(inStream)
  106.         ,    MPreference<LControl,int32>(this, inStream)
  107.         {
  108.         }
  109.     virtual ~CIntPrefRadio()
  110.         {
  111.             // Only the radio button with an ON value writes its value out.
  112.             // An int preference writes out its ordinal.
  113.             if (mPaneSelf->GetValue() != 0)
  114.                 WriteSelf();
  115.         }
  116.     enum { class_ID = 'Irad' };
  117.     virtual void FinishCreateSelf()
  118.         {
  119.             LGARadioButton::FinishCreateSelf();
  120.             MPreferenceBase::FinishCreate();
  121.         }
  122. }; // class CIntPrefRadio
  123.  
  124. #pragma mark ---CPrefColorButton---
  125. //======================================
  126. class CPrefColorButton
  127. //======================================
  128. :    public CColorButton
  129. ,    public MPreference<CColorButton,RGBColor>
  130. {
  131. public:
  132.     enum { class_ID = 'Pcol' };
  133.     CPrefColorButton(LStream* inStream)
  134.         :    CColorButton(inStream)
  135.         ,    MPreference<CColorButton,RGBColor>((CColorButton*)this, inStream)
  136.         {
  137.         }
  138.     virtual ~CPrefColorButton()
  139.         {
  140.             WriteSelf();
  141.         }
  142.     virtual void FinishCreateSelf()
  143.         {
  144.             CColorButton::FinishCreateSelf();
  145.             MPreferenceBase::FinishCreate();
  146.         }
  147. }; // class CPrefColorButton
  148.  
  149. #pragma mark ---CIntPrefPopup---
  150. //======================================
  151. class CIntPrefPopup
  152. // NOTE: There are two modes of operation: command mode and item mode.
  153. // Command mode happens if mNumCommands > 0, otherwise item mode obtains.
  154. // In item mode, unlike the base class LGAPopup, the values are zero based.  I.e., the
  155. // first menu item represents a pref value of zero.
  156. // In command mode, the command numbers of the items are used for the pref values,
  157. // allowing the menu items to represent non-consecutive pref values, or reordered
  158. // pref values.
  159. //======================================
  160. :    public LGAPopup
  161. ,    public MPreference<LControl,int32>
  162. {
  163. public:
  164.     CIntPrefPopup(LStream* inStream)
  165.         :    LGAPopup(inStream)
  166.         ,    MPreference<LControl,int32>(this, inStream)
  167.         {
  168.         }
  169.     virtual ~CIntPrefPopup()
  170.         {
  171.             WriteSelf();
  172.         }
  173.     enum { class_ID = 'Ppop' };
  174.     virtual void FinishCreateSelf()
  175.         {
  176.             LGAPopup::FinishCreateSelf();
  177.             MPreferenceBase::FinishCreate();
  178.         }
  179.     virtual int32 GetPaneValue() const
  180.         {
  181.             Int32 itemNumber = LGAPopup::GetValue();
  182.             // Use the command nums, if provided.
  183.             if (mNumCommands > 0)
  184.                 return (*mCommandNums)[itemNumber - 1];
  185.             // Otherwise, use the menu item number - 1 (it's zero based).
  186.             return itemNumber - 1;
  187.         }
  188.     virtual void SetPaneValue(int32 inData)
  189.         {
  190.             if (mNumCommands == 0)
  191.             {
  192.                 // Item mode.
  193.                 LGAPopup::SetValue(inData + 1); // first item's value is zero.
  194.             }
  195.             else
  196.             {
  197.                 // Command mode.
  198.                 CommandT* cur = *mCommandNums;
  199.                 for (int item = 1; item <= mNumCommands; item++, cur++)
  200.                 {
  201.                     if (*cur == inData)
  202.                     {
  203.                         SetValue(item);
  204.                         break;
  205.                     }
  206.                 }
  207.             }
  208.         }
  209.  
  210. }; // class CIntPrefPopup
  211.  
  212. #pragma mark ---CTextPrefPopup---
  213. //======================================
  214. class CTextPrefPopup
  215. //======================================
  216. :    public LGAPopup
  217. ,    public MPreference<LGAPopup,char*>
  218. {
  219. public:
  220.     CTextPrefPopup(LStream* inStream)
  221.         :    LGAPopup(inStream)
  222.         ,    MPreference<LGAPopup,char*>(this, inStream)
  223.         {
  224.         }
  225.     virtual ~CTextPrefPopup()
  226.         {
  227.             WriteSelf();
  228.         }
  229.     enum { class_ID = 'Tpop' };
  230.     virtual void FinishCreateSelf()
  231.         {
  232.             LGAPopup::FinishCreateSelf();
  233.             MPreferenceBase::FinishCreate();
  234.         }
  235. }; // class CTextPrefPopup
  236.  
  237. #pragma mark ---CPrefEditText---
  238. //======================================
  239. class CPrefTextEdit
  240. //======================================
  241. :    public CValidEditField
  242. ,    public MPreference<LTextEdit,char*>
  243. {
  244. public:
  245.     CPrefTextEdit(LStream* inStream)
  246.         :    CValidEditField(inStream)
  247.         ,    MPreference<LTextEdit,char*>((LTextEdit*)this, inStream)
  248.         {
  249.         }
  250.     virtual ~CPrefTextEdit()
  251.         {
  252.             // A textedit field always writes its value out.
  253.             WriteSelf();
  254.         }
  255.     enum { class_ID = 'Pedt' };
  256.     virtual void FinishCreateSelf()
  257.         {
  258.             CValidEditField::FinishCreateSelf();
  259.             MPreferenceBase::FinishCreate();
  260.             // The edit field with mOrdinal == 1 should become target:
  261.             if (mOrdinal == 1)
  262.                 ((CValidEditField*)mPaneSelf)->GetSuperCommander()->SetLatentSub(this);
  263.         }
  264. }; // class CPrefTextEdit
  265.  
  266. #pragma mark ---CIntPrefTextEdit---
  267. //======================================
  268. class CIntPrefTextEdit
  269. // // Note: use CPrefTextEdit template in constructor, just change the class ID to 'Iedt'.
  270. //======================================
  271. :    public CValidEditField
  272. ,    public MPreference<LTextEdit,int32>
  273. {
  274. public:
  275.     enum { class_ID = 'Iedt' };
  276.     CIntPrefTextEdit(LStream* inStream)
  277.         :    CValidEditField(inStream)
  278.         ,    MPreference<LTextEdit,int32>((LTextEdit*)this, inStream)
  279.         {
  280.         }
  281.     virtual ~CIntPrefTextEdit()
  282.         {
  283.             // A textedit field always writes its value out.
  284.             WriteSelf();
  285.         }
  286.     virtual void FinishCreateSelf()
  287.         {
  288.             CValidEditField::FinishCreateSelf();
  289.             MPreferenceBase::FinishCreate();
  290.             // The edit field with mOrdinal == 1 should become target:
  291.             if (mOrdinal == 1)
  292.                 ((CValidEditField*)mPaneSelf)->GetSuperCommander()->SetLatentSub(this);
  293.         }
  294. }; // class CIntPrefTextEdit
  295.  
  296. #pragma mark ---CPrefFilePicker---
  297. //======================================
  298. class CPrefFilePicker
  299. // mOrdinal determines the PickEnum.
  300. //======================================
  301. :    public CFilePicker
  302. ,    public MPreferenceBase // binary data
  303. {
  304. public:
  305.     enum { class_ID = 'Pfpk' };
  306.     typedef int    (*PrefReadFunc)(const char*, void**, int*);
  307.     CPrefFilePicker(LStream* inStream)
  308.         :    CFilePicker(inStream)
  309.         ,    MPreferenceBase((CFilePicker*)this, inStream)
  310.         {
  311.             CFilePicker::SetPickType((PickEnum)mOrdinal);
  312.         }
  313.     virtual ~CPrefFilePicker()
  314.         {
  315.             if (ShouldWrite())
  316.             {
  317.                 if (CFilePicker::WasSet())
  318.                 {
  319.                     FSSpec fileSpec = CFilePicker::GetFSSpec();
  320.                     AliasHandle a = NULL;
  321.                     OSErr iErr = NewAlias(nil, &fileSpec, &a);
  322.                     if (!iErr)
  323.                     {
  324.                         Size iByteCnt = GetHandleSize((Handle)a);
  325.                         HLock((Handle)a);
  326.                         PREF_SetBinaryPref(mName, *a, iByteCnt);
  327.                         DisposeHandle((Handle)a);
  328.                     }
  329.                 }
  330.             }
  331.         }
  332.     virtual Boolean Changed() const
  333.         {
  334.             return CFilePicker::WasSet();
  335.         }
  336.     virtual void FinishCreateSelf()
  337.         {
  338.             CFilePicker::FinishCreateSelf();
  339.             MPreferenceBase::FinishCreate();
  340.         }
  341.     virtual void InitializeUsing(PrefReadFunc inFunc)
  342.         {
  343.             // Read old alias pref from resource
  344.             // XP prefs: Read alias as binary type
  345.             AliasHandle alias = nil;
  346.             int size;
  347.             void* a;
  348.             if (inFunc(mName, &a, &size ) == 0)
  349.             {
  350.                 PtrToHand(a, &(Handle)alias, size);
  351.                 XP_FREE(a);
  352.             }
  353.             if (alias && *alias)
  354.             {
  355.                 FSSpec fileSpec;
  356.                 fileSpec.vRefNum = fileSpec.parID = -1;
  357.                 fileSpec.name[0] = '\0';
  358.  
  359.                 Boolean    ignore;
  360.                 OSErr err = ::ResolveAlias(NULL, alias, &fileSpec, &ignore);
  361.                 if (err != noErr)
  362.                     fileSpec.vRefNum = fileSpec.parID = -1;
  363.                 if (CFileMgr::FileExists(fileSpec))
  364.                 {
  365.                     StSetBroadcasting dontBroadcast((CFilePicker*)this, false);
  366.                     CFilePicker::SetFSSpec(fileSpec);
  367.                 }
  368.             }
  369.             if (alias)
  370.                 DisposeHandle((Handle)alias);
  371.         }
  372.     virtual void ReadSelf()
  373.         {
  374.             InitializeUsing(PREF_CopyBinaryPref);
  375.         }
  376.     virtual void ReadDefaultSelf()
  377.         {
  378.             if (!IsLocked())
  379.                 InitializeUsing(PREF_CopyDefaultBinaryPref);
  380.         }
  381. }; // class CPrefFilePicker
  382.  
  383. #ifdef MOZ_MAIL_NEWS
  384. #include "macutil.h"
  385. #include "UNewFolderDialog.h"
  386. #include "CMessageFolder.h"
  387.  
  388. //======================================
  389. class CSpecialFolderCheckbox
  390. // Like a pref checkbox, but the descriptor is derived from a second, text preference.
  391. // The second pref name is obtained from the main (boolean) one by replacing the substring
  392. // "use" by the substring "default", eg
  393. //        mail.use_fcc -> mail.default_fcc
  394. // This conversion allows us to share the constructor template.  This guy can just have
  395. // a different class ID.
  396. //======================================
  397. :    public CPrefCheckbox
  398. {
  399. private:
  400.     typedef CPrefCheckbox Inherited;
  401. public:
  402.     enum { class_ID = 'FLck' };
  403.                     CSpecialFolderCheckbox(LStream* inStream);
  404.     virtual            ~CSpecialFolderCheckbox();
  405.     virtual void    FinishCreateSelf();
  406.     void            SetTitleUsing(const CStr255& folderName, const CStr255& serverName);
  407.  
  408. protected:
  409.     char*    mCaptionPrefName;
  410.     char*    mFormatString;
  411. }; // class CSpecialFolderCheckbox
  412.  
  413. #pragma mark ---CSpecialFolderCheckbox---
  414.  
  415. //-----------------------------------
  416. CSpecialFolderCheckbox::CSpecialFolderCheckbox(LStream* inStream)
  417. //-----------------------------------
  418. :    CPrefCheckbox(inStream)
  419. ,    mCaptionPrefName(nil)
  420. ,    mFormatString(nil)
  421. {
  422.     LStr255 originalName = mName;
  423.     UInt8 position = originalName.Find(".use_", 1);
  424.     originalName.Replace(position, strlen(".use_"), ".default_", strlen(".default_"));
  425.     mCaptionPrefName = XP_STRDUP((const char*)CStr255(ConstStringPtr(originalName)));
  426.     // The initial descriptor is the format string.
  427.     CStr255 text;
  428.     GetDescriptor(text);
  429.     mFormatString = XP_STRDUP((char*)text);
  430. }
  431.  
  432. //-----------------------------------
  433. CSpecialFolderCheckbox::~CSpecialFolderCheckbox()
  434. //-----------------------------------
  435. {
  436.     XP_FREEIF(mCaptionPrefName);
  437.     XP_FREEIF(mFormatString);
  438. }
  439.  
  440. //-----------------------------------
  441. void CSpecialFolderCheckbox::FinishCreateSelf()
  442. //-----------------------------------
  443. {
  444.     Inherited::FinishCreateSelf();
  445.     
  446.     CStr255 folderName;
  447.     CMessageFolder folder, server;
  448.     UFolderDialogs::GetFolderAndServerNames(
  449.                     mCaptionPrefName,
  450.                     folder,
  451.                     folderName,
  452.                     server);
  453.     
  454.     SetTitleUsing(folderName, server.GetPrettyName());
  455. }
  456.  
  457. //-----------------------------------
  458. void CSpecialFolderCheckbox::SetTitleUsing(
  459.     const CStr255& folderName,
  460.     const CStr255& serverName)
  461. //-----------------------------------
  462. {
  463.     CStr255 title(mFormatString);
  464.     StringParamText(title, folderName, serverName);
  465.     SetDescriptor(title);
  466. }
  467.  
  468. //-----------------------------------
  469. void UPrefControls::NoteSpecialFolderChanged(
  470.     LControl* inControl,
  471.     int inKind,
  472.     const CMessageFolder& inFolder)
  473. // The control is a checkbox displaying (e.g.) "Sent Mail on FooServer". This routine updates
  474. // the title after the choice of folder or server has changed.
  475. //-----------------------------------
  476. {
  477.     CSpecialFolderCheckbox* cb = dynamic_cast<CSpecialFolderCheckbox*>(inControl);
  478.     if (cb)
  479.     {
  480.         CStr255 folderName;
  481.         CMessageFolder server;
  482.         UFolderDialogs::GetFolderAndServerNames(
  483.                         inFolder,
  484.                         (UFolderDialogs::FolderKind)inKind,
  485.                         folderName,
  486.                         server);
  487.         cb->SetTitleUsing(folderName, server.GetName());
  488.     }
  489. }
  490.  
  491. #endif // MOZ_MAIL_NEWS
  492.  
  493. //-----------------------------------
  494. void UPrefControls::RegisterPrefControlViews()
  495. //-----------------------------------
  496. {
  497.     RegisterClass_(CPrefCheckbox);
  498.     RegisterClass_(CIntPrefRadio);
  499.     RegisterClass_(CBoolPrefRadio);
  500.     RegisterClass_(CPrefTextEdit);
  501.     RegisterClass_(CIntPrefTextEdit);
  502.     RegisterClass_(CIntPrefPopup);
  503.     RegisterClass_(CTextPrefPopup);
  504.     RegisterClass_(CPrefFilePicker);
  505.     RegisterClass_(CPrefColorButton);
  506. #ifdef MOZ_MAIL_NEWS
  507.     RegisterClass_(CSpecialFolderCheckbox);
  508. #endif // MOZ_MAIL_NEWS
  509. }
  510.