home *** CD-ROM | disk | FTP | other *** search
- /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- *
- * The contents of this file are subject to the Netscape Public License
- * Version 1.0 (the "NPL"); you may not use this file except in
- * compliance with the NPL. You may obtain a copy of the NPL at
- * http://www.mozilla.org/NPL/
- *
- * Software distributed under the NPL is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
- * for the specific language governing rights and limitations under the
- * NPL.
- *
- * The Initial Developer of this code under the NPL is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1998 Netscape Communications Corporation. All Rights
- * Reserved.
- */
-
- #include "PrefControls.h"
-
- #include "MPreference.h"
- #include "CValidEditField.h"
-
- #include "prefwutil.h"
- #include "prefapi.h"
- #include "ufilemgr.h"
- #include "StSetBroadcasting.h"
-
- #include "xp_mcom.h"
-
- #include <LGACheckbox.h>
- #include <LGARadioButton.h>
- #include <LGAPopup.h>
-
- // Note. We can do java-style 'inline' virtual functions here, because these classes
- // all have file scope. If you ever move these declarations to a header, you
- // should non-inline 'em.
-
- #pragma mark ---CPrefCheckbox---
- //======================================
- class CPrefCheckbox
- //======================================
- : public LGACheckbox
- , public MPreference<LControl,XP_Bool>
- {
- public:
- CPrefCheckbox(LStream* inStream)
- : LGACheckbox(inStream)
- , MPreference<LControl,XP_Bool>(this, inStream)
- {
- }
- virtual ~CPrefCheckbox()
- {
- WriteSelf();
- // checkbox always writes its pane value ^ its ordinal.
- // Thus: if mOrdinal == 1, the checkbox reverses the sense of the pref.
- }
- enum { class_ID = 'Pchk' };
- virtual void FinishCreateSelf()
- {
- LGACheckbox::FinishCreateSelf();
- MPreferenceBase::FinishCreate();
- }
- }; // class CPrefCheckbox
-
- #pragma mark ---CBoolPrefRadio---
- //======================================
- class CBoolPrefRadio
- // Actually, because of the writing-out policy, only the zero-ordinal radio button
- // needs to be a CBoolPrefRadio. The other one can be just a LGARadioButton.
- //======================================
- : public LGARadioButton
- , public MPreference<LControl,XP_Bool>
- {
- public:
- CBoolPrefRadio(LStream* inStream)
- : LGARadioButton(inStream)
- , MPreference<LControl,XP_Bool>(this, inStream)
- {
- }
- virtual ~CBoolPrefRadio()
- {
- // Only the radio button with a zero ordinal writes its value out.
- // It writes out its pane value.
- if (mOrdinal == 0)
- WriteSelf();
- }
- enum { class_ID = 'Brad' };
- virtual void FinishCreateSelf()
- {
- LGARadioButton::FinishCreateSelf();
- MPreferenceBase::FinishCreate();
- }
- }; // class CBoolPrefRadio
-
- #pragma mark ---CIntPrefRadio---
- //======================================
- class CIntPrefRadio
- //======================================
- : public LGARadioButton
- , public MPreference<LControl,int32>
- {
- public:
- CIntPrefRadio(LStream* inStream)
- : LGARadioButton(inStream)
- , MPreference<LControl,int32>(this, inStream)
- {
- }
- virtual ~CIntPrefRadio()
- {
- // Only the radio button with an ON value writes its value out.
- // An int preference writes out its ordinal.
- if (mPaneSelf->GetValue() != 0)
- WriteSelf();
- }
- enum { class_ID = 'Irad' };
- virtual void FinishCreateSelf()
- {
- LGARadioButton::FinishCreateSelf();
- MPreferenceBase::FinishCreate();
- }
- }; // class CIntPrefRadio
-
- #pragma mark ---CPrefColorButton---
- //======================================
- class CPrefColorButton
- //======================================
- : public CColorButton
- , public MPreference<CColorButton,RGBColor>
- {
- public:
- enum { class_ID = 'Pcol' };
- CPrefColorButton(LStream* inStream)
- : CColorButton(inStream)
- , MPreference<CColorButton,RGBColor>((CColorButton*)this, inStream)
- {
- }
- virtual ~CPrefColorButton()
- {
- WriteSelf();
- }
- virtual void FinishCreateSelf()
- {
- CColorButton::FinishCreateSelf();
- MPreferenceBase::FinishCreate();
- }
- }; // class CPrefColorButton
-
- #pragma mark ---CIntPrefPopup---
- //======================================
- class CIntPrefPopup
- // NOTE: There are two modes of operation: command mode and item mode.
- // Command mode happens if mNumCommands > 0, otherwise item mode obtains.
- // In item mode, unlike the base class LGAPopup, the values are zero based. I.e., the
- // first menu item represents a pref value of zero.
- // In command mode, the command numbers of the items are used for the pref values,
- // allowing the menu items to represent non-consecutive pref values, or reordered
- // pref values.
- //======================================
- : public LGAPopup
- , public MPreference<LControl,int32>
- {
- public:
- CIntPrefPopup(LStream* inStream)
- : LGAPopup(inStream)
- , MPreference<LControl,int32>(this, inStream)
- {
- }
- virtual ~CIntPrefPopup()
- {
- WriteSelf();
- }
- enum { class_ID = 'Ppop' };
- virtual void FinishCreateSelf()
- {
- LGAPopup::FinishCreateSelf();
- MPreferenceBase::FinishCreate();
- }
- virtual int32 GetPaneValue() const
- {
- Int32 itemNumber = LGAPopup::GetValue();
- // Use the command nums, if provided.
- if (mNumCommands > 0)
- return (*mCommandNums)[itemNumber - 1];
- // Otherwise, use the menu item number - 1 (it's zero based).
- return itemNumber - 1;
- }
- virtual void SetPaneValue(int32 inData)
- {
- if (mNumCommands == 0)
- {
- // Item mode.
- LGAPopup::SetValue(inData + 1); // first item's value is zero.
- }
- else
- {
- // Command mode.
- CommandT* cur = *mCommandNums;
- for (int item = 1; item <= mNumCommands; item++, cur++)
- {
- if (*cur == inData)
- {
- SetValue(item);
- break;
- }
- }
- }
- }
-
- }; // class CIntPrefPopup
-
- #pragma mark ---CTextPrefPopup---
- //======================================
- class CTextPrefPopup
- //======================================
- : public LGAPopup
- , public MPreference<LGAPopup,char*>
- {
- public:
- CTextPrefPopup(LStream* inStream)
- : LGAPopup(inStream)
- , MPreference<LGAPopup,char*>(this, inStream)
- {
- }
- virtual ~CTextPrefPopup()
- {
- WriteSelf();
- }
- enum { class_ID = 'Tpop' };
- virtual void FinishCreateSelf()
- {
- LGAPopup::FinishCreateSelf();
- MPreferenceBase::FinishCreate();
- }
- }; // class CTextPrefPopup
-
- #pragma mark ---CPrefEditText---
- //======================================
- class CPrefTextEdit
- //======================================
- : public CValidEditField
- , public MPreference<LTextEdit,char*>
- {
- public:
- CPrefTextEdit(LStream* inStream)
- : CValidEditField(inStream)
- , MPreference<LTextEdit,char*>((LTextEdit*)this, inStream)
- {
- }
- virtual ~CPrefTextEdit()
- {
- // A textedit field always writes its value out.
- WriteSelf();
- }
- enum { class_ID = 'Pedt' };
- virtual void FinishCreateSelf()
- {
- CValidEditField::FinishCreateSelf();
- MPreferenceBase::FinishCreate();
- // The edit field with mOrdinal == 1 should become target:
- if (mOrdinal == 1)
- ((CValidEditField*)mPaneSelf)->GetSuperCommander()->SetLatentSub(this);
- }
- }; // class CPrefTextEdit
-
- #pragma mark ---CIntPrefTextEdit---
- //======================================
- class CIntPrefTextEdit
- // // Note: use CPrefTextEdit template in constructor, just change the class ID to 'Iedt'.
- //======================================
- : public CValidEditField
- , public MPreference<LTextEdit,int32>
- {
- public:
- enum { class_ID = 'Iedt' };
- CIntPrefTextEdit(LStream* inStream)
- : CValidEditField(inStream)
- , MPreference<LTextEdit,int32>((LTextEdit*)this, inStream)
- {
- }
- virtual ~CIntPrefTextEdit()
- {
- // A textedit field always writes its value out.
- WriteSelf();
- }
- virtual void FinishCreateSelf()
- {
- CValidEditField::FinishCreateSelf();
- MPreferenceBase::FinishCreate();
- // The edit field with mOrdinal == 1 should become target:
- if (mOrdinal == 1)
- ((CValidEditField*)mPaneSelf)->GetSuperCommander()->SetLatentSub(this);
- }
- }; // class CIntPrefTextEdit
-
- #pragma mark ---CPrefFilePicker---
- //======================================
- class CPrefFilePicker
- // mOrdinal determines the PickEnum.
- //======================================
- : public CFilePicker
- , public MPreferenceBase // binary data
- {
- public:
- enum { class_ID = 'Pfpk' };
- typedef int (*PrefReadFunc)(const char*, void**, int*);
- CPrefFilePicker(LStream* inStream)
- : CFilePicker(inStream)
- , MPreferenceBase((CFilePicker*)this, inStream)
- {
- CFilePicker::SetPickType((PickEnum)mOrdinal);
- }
- virtual ~CPrefFilePicker()
- {
- if (ShouldWrite())
- {
- if (CFilePicker::WasSet())
- {
- FSSpec fileSpec = CFilePicker::GetFSSpec();
- AliasHandle a = NULL;
- OSErr iErr = NewAlias(nil, &fileSpec, &a);
- if (!iErr)
- {
- Size iByteCnt = GetHandleSize((Handle)a);
- HLock((Handle)a);
- PREF_SetBinaryPref(mName, *a, iByteCnt);
- DisposeHandle((Handle)a);
- }
- }
- }
- }
- virtual Boolean Changed() const
- {
- return CFilePicker::WasSet();
- }
- virtual void FinishCreateSelf()
- {
- CFilePicker::FinishCreateSelf();
- MPreferenceBase::FinishCreate();
- }
- virtual void InitializeUsing(PrefReadFunc inFunc)
- {
- // Read old alias pref from resource
- // XP prefs: Read alias as binary type
- AliasHandle alias = nil;
- int size;
- void* a;
- if (inFunc(mName, &a, &size ) == 0)
- {
- PtrToHand(a, &(Handle)alias, size);
- XP_FREE(a);
- }
- if (alias && *alias)
- {
- FSSpec fileSpec;
- fileSpec.vRefNum = fileSpec.parID = -1;
- fileSpec.name[0] = '\0';
-
- Boolean ignore;
- OSErr err = ::ResolveAlias(NULL, alias, &fileSpec, &ignore);
- if (err != noErr)
- fileSpec.vRefNum = fileSpec.parID = -1;
- if (CFileMgr::FileExists(fileSpec))
- {
- StSetBroadcasting dontBroadcast((CFilePicker*)this, false);
- CFilePicker::SetFSSpec(fileSpec);
- }
- }
- if (alias)
- DisposeHandle((Handle)alias);
- }
- virtual void ReadSelf()
- {
- InitializeUsing(PREF_CopyBinaryPref);
- }
- virtual void ReadDefaultSelf()
- {
- if (!IsLocked())
- InitializeUsing(PREF_CopyDefaultBinaryPref);
- }
- }; // class CPrefFilePicker
-
- #ifdef MOZ_MAIL_NEWS
- #include "macutil.h"
- #include "UNewFolderDialog.h"
- #include "CMessageFolder.h"
-
- //======================================
- class CSpecialFolderCheckbox
- // Like a pref checkbox, but the descriptor is derived from a second, text preference.
- // The second pref name is obtained from the main (boolean) one by replacing the substring
- // "use" by the substring "default", eg
- // mail.use_fcc -> mail.default_fcc
- // This conversion allows us to share the constructor template. This guy can just have
- // a different class ID.
- //======================================
- : public CPrefCheckbox
- {
- private:
- typedef CPrefCheckbox Inherited;
- public:
- enum { class_ID = 'FLck' };
- CSpecialFolderCheckbox(LStream* inStream);
- virtual ~CSpecialFolderCheckbox();
- virtual void FinishCreateSelf();
- void SetTitleUsing(const CStr255& folderName, const CStr255& serverName);
-
- protected:
- char* mCaptionPrefName;
- char* mFormatString;
- }; // class CSpecialFolderCheckbox
-
- #pragma mark ---CSpecialFolderCheckbox---
-
- //-----------------------------------
- CSpecialFolderCheckbox::CSpecialFolderCheckbox(LStream* inStream)
- //-----------------------------------
- : CPrefCheckbox(inStream)
- , mCaptionPrefName(nil)
- , mFormatString(nil)
- {
- LStr255 originalName = mName;
- UInt8 position = originalName.Find(".use_", 1);
- originalName.Replace(position, strlen(".use_"), ".default_", strlen(".default_"));
- mCaptionPrefName = XP_STRDUP((const char*)CStr255(ConstStringPtr(originalName)));
- // The initial descriptor is the format string.
- CStr255 text;
- GetDescriptor(text);
- mFormatString = XP_STRDUP((char*)text);
- }
-
- //-----------------------------------
- CSpecialFolderCheckbox::~CSpecialFolderCheckbox()
- //-----------------------------------
- {
- XP_FREEIF(mCaptionPrefName);
- XP_FREEIF(mFormatString);
- }
-
- //-----------------------------------
- void CSpecialFolderCheckbox::FinishCreateSelf()
- //-----------------------------------
- {
- Inherited::FinishCreateSelf();
-
- CStr255 folderName;
- CMessageFolder folder, server;
- UFolderDialogs::GetFolderAndServerNames(
- mCaptionPrefName,
- folder,
- folderName,
- server);
-
- SetTitleUsing(folderName, server.GetPrettyName());
- }
-
- //-----------------------------------
- void CSpecialFolderCheckbox::SetTitleUsing(
- const CStr255& folderName,
- const CStr255& serverName)
- //-----------------------------------
- {
- CStr255 title(mFormatString);
- StringParamText(title, folderName, serverName);
- SetDescriptor(title);
- }
-
- //-----------------------------------
- void UPrefControls::NoteSpecialFolderChanged(
- LControl* inControl,
- int inKind,
- const CMessageFolder& inFolder)
- // The control is a checkbox displaying (e.g.) "Sent Mail on FooServer". This routine updates
- // the title after the choice of folder or server has changed.
- //-----------------------------------
- {
- CSpecialFolderCheckbox* cb = dynamic_cast<CSpecialFolderCheckbox*>(inControl);
- if (cb)
- {
- CStr255 folderName;
- CMessageFolder server;
- UFolderDialogs::GetFolderAndServerNames(
- inFolder,
- (UFolderDialogs::FolderKind)inKind,
- folderName,
- server);
- cb->SetTitleUsing(folderName, server.GetName());
- }
- }
-
- #endif // MOZ_MAIL_NEWS
-
- //-----------------------------------
- void UPrefControls::RegisterPrefControlViews()
- //-----------------------------------
- {
- RegisterClass_(CPrefCheckbox);
- RegisterClass_(CIntPrefRadio);
- RegisterClass_(CBoolPrefRadio);
- RegisterClass_(CPrefTextEdit);
- RegisterClass_(CIntPrefTextEdit);
- RegisterClass_(CIntPrefPopup);
- RegisterClass_(CTextPrefPopup);
- RegisterClass_(CPrefFilePicker);
- RegisterClass_(CPrefColorButton);
- #ifdef MOZ_MAIL_NEWS
- RegisterClass_(CSpecialFolderCheckbox);
- #endif // MOZ_MAIL_NEWS
- }
-