home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / macfe / central / uprefd.cp < prev    next >
Encoding:
Text File  |  1998-04-08  |  86.7 KB  |  2,737 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 "uprefd.h"
  20.  
  21. // macfe
  22. #include "ufilemgr.h"                // CFileMgr
  23. #include "macutil.h"                // CStringListRsrc
  24. #include "resgui.h"                    // res_Strings1, res_Strings2, res_StringsBoolean
  25. #include "mregistr.h"                // CNotifierRegistry
  26. #include "uerrmgr.h"                // ErrorManager
  27. #include "uapp.h"                    // FILE_TYPE_PROFILES, STARTUP_TYPE_NETPROFILE
  28. #include "macfeprefs.h"                // prototypes for FindGutsFolder, FindNetscapeFolder, FindJavaDownloadsFolder
  29. #include "CToolTipAttachment.h"
  30. #include "InternetConfig.h"            // CInternetConfigInterface
  31. #include "CSpinningN.h"
  32. #include "profile.h"                // kProfileStrings
  33.  
  34. #include <LBroadcaster.h>
  35.  
  36. // Netscape
  37. #include "glhist.h"                    // GH_SetGlobalHistoryTimeout
  38. #include "net.h"                    // PROXY_STYLE_AUTOMATIC
  39. #include "ntypes.h"
  40. #include "shistele.h"
  41. #include "proto.h"
  42. #ifndef _XP_H_
  43. //#include "xp_mcom.h"
  44. #endif
  45. #include "msgcom.h"                    // MSG_NormalSize, MSG_PlainFont
  46. #include "mime.h"                    // MIME_ConformToStandard
  47. #include "fe_proto.h"                // prototype for FE_GetNetHelpDir
  48. #include "java.h"                    // LJ_SetJavaEnabled
  49.  
  50. #include "prefapi.h"        // ns/modules/libpref
  51.  
  52. /*********************************************************************************
  53.  * DOGBERT XP PREFERENCES / MULTI-USER PROFILES
  54.  *
  55.  * New preference file format: XP text file parsed by JavaScript via libpref
  56.  *    (includes all user strings, bools, ints, and colors).
  57.  * Some prefs (see below) are still written in old resource format.
  58.  * Both old and new prefs are read & written to the existing Netscape Prefs file.
  59.  *
  60.  * Primary changes to this file:
  61.  *    - added GetUserProfile() and InitPrefsFolder() to prompt user for desired
  62.  *      profile (if necessary) and use that to point to base Preferences folder.
  63.  *    - changed order of PrefEnum entries and added XP prefName strings.
  64.  *    - ReadPreference, if it detects new format, only needs to call 
  65.  *      PostProcessPrefChange for each pref to propagate the new value.
  66.  *      Calls to back-end will GO AWAY as modules fetch their own pref values.
  67.  *    - ReadPreference otherwise reads old-format file.
  68.  *    - WritePreference always writes new format.
  69.  *    - CPrefs Get/Setters use libpref calls.
  70.  *    - removed CPrefs storage of strings, bools, ints, and colors.
  71.  *    - file/folder aliases accessed as libpref binary types but still stored
  72.  *      in CPrefs via sFileIDs.
  73.  *
  74.  * Some prefs are not yet supported in XP format.  
  75.  *    - font encodings
  76.  *    - window/pane positions
  77.  *    - protocol handlers, etc.
  78.  * We at least should support the first in XP format for use by Admin Kit.
  79.  *********************************************************************************/
  80.  
  81. const Int16        refNum_Undefined    = -1;    // Really defined in LFile.cp
  82.  
  83. static LBroadcaster * gPrefBroadcaster = NULL;
  84.  
  85. //===============================================================================
  86. // Resource definitions
  87. // definitions of type and resource location of all preferences
  88. //===============================================================================
  89.  
  90. #define NOTSAVED    'NONE'
  91. #define STRINGLIST    'STR#'
  92. #define ALIASREC    'ALIS'
  93. #define PRINTRECORD    'PrRc'
  94. #define REVISION    'PRev'
  95. #define WINDOWREC    'WPSt'    // Starts off with a rect, followed by variable data for each window
  96.  
  97. #define REVISION_RES_ID 10000
  98. // Resource IDs of all resources used in prefs
  99. // are defined in resgui.h
  100.  
  101. enum PrefType    {
  102.     eStringType,
  103.     eBooleanType,
  104.     eFileSpecType,
  105.     eLongType,
  106.     eColorType,
  107.     ePrintRecordType,
  108.     eNoType
  109. };
  110.  
  111. struct PrefLoc {
  112.     CPrefs::PrefEnum    prefID;    // What's my id
  113.     OSType        resType;        // What kind of resource are we reading
  114.     PrefType    prefType;    // How should we store this pref natively
  115.     short        resID;        // Resource ID
  116.     short        refCon;        // For STRINGLIST this is the index into the resource
  117.                             // For ALIASREC, 1 to pop up alert when not found, 0 no alert
  118.     char*        prefName;    // XP pref name
  119. };
  120.  
  121. // This array defines what kind of preference each PrefEnum is,
  122. // and where it is stored.
  123.  
  124. static PrefLoc    prefLoc[] =
  125. {
  126. // Folders -- need to be before anything else, because we do not have the accumulator
  127.     {    CPrefs::DownloadFolder,        ALIASREC,    eFileSpecType, 129, 1,
  128.         "browser.download_directory"},
  129.     {    CPrefs::NetscapeFolder,        NOTSAVED,    eFileSpecType, 0, 1},
  130.     {    CPrefs::MainFolder,            NOTSAVED,    eFileSpecType, 0, 1},
  131.     {    CPrefs::UsersFolder,        NOTSAVED,    eFileSpecType, 0, 1},
  132.     {    CPrefs::DiskCacheFolder,    ALIASREC,    eFileSpecType, 133, 1,
  133.         "browser.cache.directory"},
  134.     {    CPrefs::SignatureFile,        ALIASREC,    eFileSpecType, 134, 1,
  135.         "mail.signature_file"},
  136.     {    CPrefs::GIFBackdropFile,    ALIASREC,    eFileSpecType, 135, 1 },
  137.     {    CPrefs::MailFolder,            ALIASREC,    eFileSpecType, 136, 1,
  138.         "mail.directory"},
  139.     {    CPrefs::NewsFolder,            NOTSAVED,    eFileSpecType, 0, 1 },
  140.     {    CPrefs::SecurityFolder,        NOTSAVED,    eFileSpecType, 0, 1 },
  141.     {    CPrefs::MailCCFile,            ALIASREC,    eFileSpecType, 137, 1,
  142.         "mail.default_fcc"},
  143.     {    CPrefs::NewsCCFile,            ALIASREC,    eFileSpecType, 138, 1,
  144.         "news.default_fcc"},
  145.     {    CPrefs::HTMLEditor,            ALIASREC,    eFileSpecType, 139, 1,
  146.         "editor.html_editor"},
  147.     {    CPrefs::ImageEditor,        ALIASREC,    eFileSpecType, 140, 1,
  148.         "editor.image_editor"},
  149.         {       CPrefs::RequiredGutsFolder,     NOTSAVED,       eFileSpecType, 0, 1},
  150.  
  151. // TJ & ROB
  152.         {       CPrefs::SARCacheFolder,         NOTSAVED,       eFileSpecType, 0, 0},
  153. // EA
  154.     {    CPrefs::NetHelpFolder,        NOTSAVED,    eFileSpecType,    0, 0},
  155.  
  156. // Strings
  157.     {    CPrefs::HomePage,             STRINGLIST, eStringType,  res_Strings1, 1,
  158.             "browser.startup.homepage" },
  159.     {    CPrefs::NewsHost,            STRINGLIST, eStringType,  res_Strings1, 2,
  160.             "network.hosts.nntp_server" },
  161.     {    CPrefs::FTPProxy,            STRINGLIST, eStringType,  res_Strings1, 3,
  162.             "network.proxy.ftp" },
  163.     {    CPrefs::GopherProxy,        STRINGLIST, eStringType,  res_Strings1, 4,
  164.             "network.proxy.gopher" },
  165.     {    CPrefs::HTTPProxy,            STRINGLIST, eStringType,  res_Strings1, 5,
  166.             "network.proxy.http" },
  167.     {    /*unused*/CPrefs::NewsProxy,            STRINGLIST, eStringType,  res_Strings1, 6 },
  168.     {    CPrefs::WAISProxy,            STRINGLIST, eStringType,  res_Strings1, 7,
  169.             "network.proxy.wais" },
  170.     {    CPrefs::FTPProxyPort,        STRINGLIST, eStringType,  res_Strings1, 8,
  171.             "network.proxy.ftp_port" },
  172.     {    CPrefs::GopherProxyPort,    STRINGLIST, eStringType,  res_Strings1, 9,
  173.             "network.proxy.gopher_port" },
  174.     {    CPrefs::HTTPProxyPort,        STRINGLIST, eStringType,  res_Strings1, 10,
  175.             "network.proxy.http_port" },
  176.     {    /*unused*/CPrefs::NewsProxyPort,        STRINGLIST, eStringType,  res_Strings1, 11 },
  177.     {    CPrefs::WAISProxyPort,        STRINGLIST, eStringType,  res_Strings1, 12,
  178.             "network.proxy.wais_port" },
  179.     {    CPrefs::NoProxies,            STRINGLIST, eStringType,  res_Strings1, 13,
  180.             "network.proxy.no_proxies_on" },
  181.     {    CPrefs::UserName,            STRINGLIST, eStringType,  res_Strings1, 14,
  182.         "mail.identity.username" },
  183.     {    CPrefs::UserEmail,            STRINGLIST, eStringType,  res_Strings1, 15,
  184.         "mail.identity.useremail" },
  185.     {    CPrefs::SMTPHost,             STRINGLIST, eStringType,  res_Strings1, 16,
  186.         "network.hosts.smtp_server" },
  187.     {    CPrefs::SOCKSHost,             STRINGLIST, eStringType,  res_Strings2, 1,
  188.         "network.hosts.socks_server" },
  189.     {    CPrefs::SOCKSPort,             STRINGLIST, eStringType,  res_Strings2, 2,
  190.         "network.hosts.socks_serverport" },
  191.     {    CPrefs::Organization,         STRINGLIST, eStringType,  res_Strings2, 3,
  192.         "mail.identity.organization" },
  193.     {    CPrefs::SSLProxy,             STRINGLIST, eStringType,  res_Strings2, 4,
  194.         "network.proxy.ssl" },
  195.     {    CPrefs::SSLProxyPort,         STRINGLIST, eStringType,  res_Strings2, 5,
  196.         "network.proxy.ssl_port" },
  197.     {    CPrefs::PopHost,             STRINGLIST, eStringType,  res_Strings2, 6,
  198.         "network.hosts.pop_server" },
  199.     {    CPrefs::AcceptLanguage,         STRINGLIST, eStringType,  res_Strings2, 7,
  200.         "intl.accept_languages" },
  201.     {    CPrefs::DefaultMailCC,        STRINGLIST, eStringType,  res_Strings2, 8,
  202.         "mail.default_cc" },
  203.     {    CPrefs::DefaultNewsCC,        STRINGLIST, eStringType,  res_Strings2, 9,
  204.         "news.default_cc" },
  205.     {    CPrefs::ReplyTo,            STRINGLIST, eStringType,  res_Strings2, 10,
  206.         "mail.identity.reply_to" },
  207.     {    CPrefs::PopID,                STRINGLIST, eStringType,  res_Strings2, 11,
  208.         "mail.pop_name" },
  209.     {    CPrefs::AutoProxyURL,        STRINGLIST, eStringType,  res_Strings2, 12,
  210.         "network.proxy.autoconfig_url" },
  211.     {    CPrefs::MailPassword,        STRINGLIST, eStringType,  res_Strings2, 13,
  212.         "mail.pop_password" },
  213.     {     CPrefs::Ciphers,            STRINGLIST,    eStringType,    res_Strings2, 14,
  214.         "security.ciphers" },    
  215.     {     CPrefs::EditorAuthor,                    STRINGLIST,    eStringType,    res_Strings2, 15,
  216.         "editor.author" },    
  217.     {     CPrefs::EditorNewDocTemplateLocation,    STRINGLIST,    eStringType,    res_Strings2, 16,
  218.         "editor.template_location" },    
  219.     {     CPrefs::EditorBackgroundImage,            STRINGLIST,    eStringType,    res_Strings2, 17,
  220.         "editor.background_image" },    
  221.     {     CPrefs::PublishLocation,                STRINGLIST,    eStringType,    res_Strings2, 18,
  222.         "editor.publish_location" },    
  223.     {     CPrefs::PublishBrowseLocation,            STRINGLIST,    eStringType,    res_Strings2, 19,
  224.         "editor.publish_browse_location" },    
  225.     {     CPrefs::PublishHistory0,                    STRINGLIST,    eStringType,    res_Strings2, 20,
  226.         "editor.publish_history_0" },    
  227.     {     CPrefs::PublishHistory1,                    STRINGLIST,    eStringType,    res_Strings2, 21,
  228.         "editor.publish_history_1" },    
  229.     {     CPrefs::PublishHistory2,                    STRINGLIST,    eStringType,    res_Strings2, 22,
  230.         "editor.publish_history_2" },    
  231.     {     CPrefs::PublishHistory3,                    STRINGLIST,    eStringType,    res_Strings2, 23,
  232.         "editor.publish_history_3" },    
  233.     {     CPrefs::PublishHistory4,                    STRINGLIST,    eStringType,    res_Strings2, 24,
  234.         "editor.publish_history_4" },    
  235.     {     CPrefs::PublishHistory5,                    STRINGLIST,    eStringType,    res_Strings2, 25,
  236.         "editor.publish_history_5" },    
  237.     {     CPrefs::PublishHistory6,                    STRINGLIST,    eStringType,    res_Strings2, 26,
  238.         "editor.publish_history_6" },    
  239.     {     CPrefs::PublishHistory7,                    STRINGLIST,    eStringType,    res_Strings2, 27,
  240.         "editor.publish_history_7" },    
  241.     {     CPrefs::PublishHistory8,                    STRINGLIST,    eStringType,    res_Strings2, 28,
  242.         "editor.publish_history_8" },    
  243.     {     CPrefs::PublishHistory9,                    STRINGLIST,    eStringType,    res_Strings2, 29,
  244.         "editor.publish_history_9" },    
  245.     {     CPrefs::DefaultPersonalCertificate,        STRINGLIST,    eStringType,    res_Strings2, 30,
  246.         "security.default_personal_cert" },    
  247. // Booleans
  248.     {    CPrefs::DelayImages,        STRINGLIST, eBooleanType,  res_StringsBoolean, 1,
  249.         "browser.delay_images"},
  250.     {    CPrefs::AnchorUnderline,    STRINGLIST, eBooleanType,  res_StringsBoolean, 2,
  251.         "browser.underline_anchors"},
  252.     {    CPrefs::ShowAllNews,        STRINGLIST, eBooleanType,  res_StringsBoolean, 3},
  253.     {    CPrefs::UseFancyFTP,        STRINGLIST, eBooleanType,  res_StringsBoolean, 4},
  254.     {    CPrefs::UseFancyNews,        STRINGLIST, eBooleanType,  res_StringsBoolean, 5,
  255.         "news.fancy_listing" },
  256.     {    CPrefs::ShowToolbar,        STRINGLIST, eBooleanType,  res_StringsBoolean, 6,
  257.         "browser.chrome.show_toolbar"},
  258.     {    CPrefs::ShowStatus,            STRINGLIST, eBooleanType,  res_StringsBoolean, 7,
  259.         "browser.chrome.show_status_bar"},
  260.     {    CPrefs::ShowURL,            STRINGLIST, eBooleanType,  res_StringsBoolean, 8,
  261.         "browser.chrome.show_url_bar"},
  262.     {    CPrefs::LoadHomePage,        STRINGLIST, eBooleanType,  res_StringsBoolean, 9, 
  263.         "browser.startup.autoload_homepage" },
  264.     {    CPrefs::ExpireNever,        STRINGLIST, eBooleanType,  res_StringsBoolean, 10,
  265.         "browser.never_expire"},
  266.     {    CPrefs::DisplayWhileLoading, STRINGLIST, eBooleanType,  res_StringsBoolean,11,
  267.         "browser.display_while_loading"},
  268.     {    CPrefs::CustomLinkColors,    STRINGLIST, eBooleanType,  res_StringsBoolean, 12,
  269.         "browser.custom_link_color"},
  270.     {    CPrefs::ShowDirectory,        STRINGLIST, eBooleanType,  res_StringsBoolean, 13,
  271.         "browser.chrome.show_directory_buttons" },
  272.     {    CPrefs::AgreedToLicense,    STRINGLIST, eBooleanType,  res_StringsBoolean, 14,
  273.         "browser.startup.agreed_to_licence" },
  274.     {    CPrefs::EnteringSecure,        STRINGLIST, eBooleanType,  res_StringsBoolean, 15,
  275.         "security.warn_entering_secure"},
  276.     {    CPrefs::LeavingSecure,        STRINGLIST, eBooleanType,  res_StringsBoolean, 16,
  277.         "security.warn_leaving_secure"},
  278.     {    CPrefs::ViewingMixed,        STRINGLIST, eBooleanType,  res_StringsBoolean, 17,
  279.         "security.warn_viewing_mixed"},
  280.     {    CPrefs::SubmittingInsecure,    STRINGLIST, eBooleanType,  res_StringsBoolean, 18,
  281.         "security.warn_submit_insecure"},
  282.     {    CPrefs::ShowSecurity,        STRINGLIST, eBooleanType,  res_StringsBoolean, 19,
  283.         "browser.chrome.show_security_bar"},
  284.     {    CPrefs::CustomVisitedColors,STRINGLIST, eBooleanType,  res_StringsBoolean, 20,
  285.         "browser.custom_visited_color"},
  286.     {    CPrefs::CustomTextColors,    STRINGLIST, eBooleanType,  res_StringsBoolean, 21,
  287.         "browser.custom_text_color"},
  288.     {    CPrefs::UseDocumentColors,    STRINGLIST, eBooleanType,  res_StringsBoolean, 22,
  289.         "browser.use_document_colors"},
  290.     {    CPrefs::AutoDetectEncoding,    STRINGLIST, eBooleanType,  res_StringsBoolean, 23,
  291.         "intl.auto_detect_encoding"},
  292.     {    CPrefs::UseSigFile,            STRINGLIST, eBooleanType,  res_StringsBoolean, 24,
  293.         "mail.use_signature_file"},
  294.     {    CPrefs::StrictlyMIME,        STRINGLIST, eBooleanType,  res_StringsBoolean, 25,
  295.         "mail.strictly_mime" },
  296.     {    CPrefs::UseUtilityBackground, STRINGLIST, eBooleanType,  res_StringsBoolean, 26,
  297.         "browser.mac.use_utility_pattern"},
  298.     {    CPrefs::MailUseFixedWidthFont, STRINGLIST, eBooleanType,  res_StringsBoolean, 27,
  299.         "mail.fixed_width_messages"},
  300.     {    CPrefs::UseMailFCC,            STRINGLIST, eBooleanType,  res_StringsBoolean, 28,
  301.         "mail.use_fcc"},
  302.     {    CPrefs::UseNewsFCC,            STRINGLIST, eBooleanType,  res_StringsBoolean, 29,
  303.         "news.use_fcc"},
  304.     {    CPrefs::LimitMessageSize,    STRINGLIST, eBooleanType,  res_StringsBoolean, 30,
  305.         "mail.limit_message_size"},
  306.     {    CPrefs::LeaveMailOnServer,    STRINGLIST, eBooleanType,  res_StringsBoolean, 31,
  307.         "mail.leave_on_server" },
  308.     {    CPrefs::MailCCSelf,            STRINGLIST, eBooleanType,  res_StringsBoolean, 32,
  309.         "mail.cc_self"},
  310.     {    CPrefs::NewsCCSelf,            STRINGLIST, eBooleanType,  res_StringsBoolean, 33,
  311.         "news.cc_self"},
  312.     {    CPrefs::BiffOn,                STRINGLIST, eBooleanType,  res_StringsBoolean, 34,
  313.         "mail.check_new_mail"},
  314.     {   CPrefs::UseMozPassword,        STRINGLIST, eBooleanType,  res_StringsBoolean, 35},
  315.     {    CPrefs::ThreadMail,            STRINGLIST, eBooleanType,  res_StringsBoolean, 36,
  316.         "mail.thread_mail"},
  317.     {    CPrefs::ThreadNews,            STRINGLIST, eBooleanType,  res_StringsBoolean, 37,
  318.         "news.thread_news"},
  319.     {    CPrefs::UseInlineViewSource,STRINGLIST, eBooleanType,  res_StringsBoolean, 38 },
  320.     {    CPrefs::AutoQuoteOnReply,    STRINGLIST, eBooleanType,  res_StringsBoolean, 39,
  321.         "mail.auto_quote"},
  322.     {    CPrefs::RememberMailPassword,    STRINGLIST, eBooleanType,  res_StringsBoolean, 40,
  323.         "mail.remember_password"},
  324.     {    CPrefs::DefaultMailDelivery,    STRINGLIST, eBooleanType,  res_StringsBoolean, 41,
  325.         "mail.deliver_immediately"},
  326.     {    CPrefs::EnableJavascript,            STRINGLIST,    eBooleanType,    res_StringsBoolean,    42,
  327.         "javascript.enabled" },
  328.     {    CPrefs::ShowToolTips,            STRINGLIST, eBooleanType,  res_StringsBoolean, 43,
  329.         "browser.mac.show_tool_tips"},
  330.     {    CPrefs::UseInternetConfig,        STRINGLIST, eBooleanType,  res_StringsBoolean, 44,
  331.         "browser.mac.use_internet_config"},
  332.     {    CPrefs::EnableJava,        STRINGLIST,    eBooleanType,    res_StringsBoolean,    45,
  333.         "security.enable_java" },
  334.     {    CPrefs::AcceptCookies,        STRINGLIST,    eBooleanType,    res_StringsBoolean,    46,
  335.         "network.cookie.warnAboutCookies" },
  336.     {    CPrefs::UseEmailAsPassword,    STRINGLIST,    eBooleanType,    res_StringsBoolean,    47,
  337.         "security.email_as_ftp_password" },
  338.     {    CPrefs::SubmitFormsByEmail,    STRINGLIST,    eBooleanType,    res_StringsBoolean,    48,
  339.         "security.submit_email_forms" },
  340.     {     CPrefs::AllowSSLDiskCaching,    STRINGLIST,    eBooleanType,    res_StringsBoolean,    49,
  341.         "browser.cache.disk_cache_ssl" },
  342.     {    CPrefs::EnableSSLv2,        STRINGLIST,    eBooleanType,    res_StringsBoolean,    50,
  343.         "security.enable_ssl2" },
  344.     {    CPrefs::EnableSSLv3,        STRINGLIST,    eBooleanType,    res_StringsBoolean,    51,
  345.         "security.enable_ssl3" },
  346.     {    CPrefs::EnableActiveScrolling, STRINGLIST,    eBooleanType,    res_StringsBoolean,    52,
  347.         "browser.mac.active_scrolling" },
  348. #ifdef FORTEZZA
  349.     {    CPrefs::FortezzaTimeoutOn,        STRINGLIST, eBooleanType,    res_StringsBoolean, 0 },
  350. #endif
  351. #ifdef EDITOR
  352.     {    CPrefs::EditorUseCustomColors,    STRINGLIST,    eBooleanType,    res_StringsBoolean, 53,
  353.         "editor.use_custom_colors" },
  354.     {    CPrefs::EditorUseBackgroundImage,    STRINGLIST,    eBooleanType,    res_StringsBoolean, 54,
  355.         "editor.use_background_image" },
  356.     {    CPrefs::PublishMaintainLinks,    STRINGLIST,    eBooleanType,    res_StringsBoolean, 55,
  357.         "editor.publish_keep_links" },
  358.     {    CPrefs::PublishKeepImages,        STRINGLIST,    eBooleanType,    res_StringsBoolean, 56,
  359.         "editor.publish_keep_images" },
  360.     {    CPrefs::ShowCopyright,            STRINGLIST,    eBooleanType,    res_StringsBoolean, 57,
  361.         "editor.show_copyright" },
  362.     {    CPrefs::ShowFileEditToolbar,    STRINGLIST,    eBooleanType,    res_StringsBoolean, 58 },
  363.     {    CPrefs::ShowCharacterToolbar,    STRINGLIST,    eBooleanType,    res_StringsBoolean, 59,
  364.         "editor.show_character_toolbar" },
  365.     {    CPrefs::ShowParagraphToolbar,    STRINGLIST,    eBooleanType,    res_StringsBoolean, 60,
  366.         "editor.show_paragraph_toolbar" },
  367. #endif EDITOR
  368.     // WARNING: If you add stuff here, the custom.r file (in projector for Browser and MailNews) must match!
  369. // Longs
  370.     {    CPrefs::DiskCacheSize,        STRINGLIST, eLongType,  res_StringsLong, 1,
  371.         "browser.cache.disk_cache_size"},
  372.     {    CPrefs::FileSortMethod,        STRINGLIST, eLongType,  res_StringsLong, 2,
  373.         "network.file_sort_method"},
  374.     {    CPrefs::ToolbarStyle,        STRINGLIST, eLongType,  res_StringsLong, 3,
  375.         "browser.chrome.toolbar_style"},
  376.     {    CPrefs::DaysTilExpire,        STRINGLIST, eLongType,  res_StringsLong, 4,
  377.         "browser.link_expiration"},
  378.     {    CPrefs::Connections,        STRINGLIST, eLongType,  res_StringsLong, 5,
  379.         "network.max_connections"},
  380.     {    CPrefs::BufferSize,            STRINGLIST, eLongType,  res_StringsLong, 6,
  381.         "network.tcpbufsize"},
  382.     {    /*unused*/CPrefs::PrintFlags,            STRINGLIST, eLongType,  res_StringsLong, 7},
  383.     {    CPrefs::NewsArticlesMax,    STRINGLIST, eLongType,  res_StringsLong, 8,
  384.         "news.max_articles"},
  385.     {    CPrefs::CheckDocuments,        STRINGLIST, eLongType,  res_StringsLong, 9,
  386.         "browser.cache.check_doc_frequency"},
  387.     {    CPrefs::DefaultCharSetID,    STRINGLIST, eLongType,  res_StringsLong, 10,
  388.         "intl.character_set"},
  389.     {    CPrefs::DefaultFontEncoding,STRINGLIST, eLongType,  res_StringsLong, 11,
  390.         "intl.font_encoding"},
  391.     {    CPrefs::BackgroundColors,    STRINGLIST, eLongType,  res_StringsLong, 12,
  392.         "browser.background_option" },
  393.     {    CPrefs::LicenseVersion,        STRINGLIST, eLongType,  res_StringsLong, 13,
  394.         "browser.startup.license_version"},
  395.     {    CPrefs::MessageFontStyle,    STRINGLIST, eLongType,  res_StringsLong, 14,
  396.         "mail.quoted_style"},
  397.     {    CPrefs::MessageFontSize,    STRINGLIST, eLongType,  res_StringsLong, 15,
  398.         "mail.quoted_size"},
  399.     {    CPrefs::MaxMessageSize,        STRINGLIST, eLongType,  res_StringsLong, 16,
  400.         "mail.max_size" },
  401.     {    CPrefs::TopLeftHeader,        STRINGLIST,    eLongType,    res_StringsLong, 17,
  402.         "browser.mac.print_header_topleft" },
  403.     {    CPrefs::TopMidHeader,        STRINGLIST,    eLongType,    res_StringsLong, 31,
  404.         "browser.mac.print_header_topmid" },
  405.     {    CPrefs::TopRightHeader,        STRINGLIST,    eLongType,    res_StringsLong, 18,
  406.         "browser.mac.print_header_topright" },
  407.     {    CPrefs::BottomLeftFooter,    STRINGLIST,    eLongType,    res_StringsLong, 19,
  408.         "browser.mac.print_header_botleft" },
  409.     {    CPrefs::BottomMidFooter,    STRINGLIST,    eLongType,    res_StringsLong, 20,
  410.         "browser.mac.print_header_botmid" },
  411.     {    CPrefs::BottomRightFooter,    STRINGLIST,    eLongType,    res_StringsLong, 21,
  412.         "browser.mac.print_header_botright" },
  413.     {    CPrefs::PrintBackground,    STRINGLIST,    eLongType,    res_StringsLong, 22,
  414.         "browser.mac.print_background" },
  415.     {    CPrefs::ProxyConfig,        STRINGLIST,    eLongType,    res_StringsLong, 23,
  416.         "network.proxy.type" },
  417.     {    CPrefs::StartupAsWhat,        STRINGLIST,    eLongType,    res_StringsLong, 24,
  418.         "browser.startup.default_window"},
  419.     {    CPrefs::StartupBitfield,    STRINGLIST,    eLongType,    res_StringsLong, 25,
  420.         "browser.mac.startup_bitfield"},
  421.     {    CPrefs::BiffTimeout,        STRINGLIST,    eLongType,    res_StringsLong, 26,
  422.         "mail.check_time"},
  423.     {    CPrefs::AskMozPassword,        STRINGLIST,    eLongType,    res_StringsLong, 27,
  424.         "security.ask_for_password"},
  425.     {    CPrefs::AskMozPassFrequency,STRINGLIST,    eLongType,    res_StringsLong, 28,
  426.         "security.password_lifetime"},
  427.     {    CPrefs::SortMailBy,            STRINGLIST,    eLongType,    res_StringsLong, 29,
  428.         "mail.sort_by"},
  429.     {    CPrefs::SortNewsBy,            STRINGLIST,    eLongType,    res_StringsLong, 30,
  430.         "news.sort_by"},
  431.     {    CPrefs::NewsPaneConfig,        STRINGLIST,    eLongType,    res_StringsLong, 32,
  432.         "news.pane_config"},
  433.     {    CPrefs::MailPaneConfig,        STRINGLIST,    eLongType,    res_StringsLong, 33,
  434.         "mail.pane_config"},
  435.     {    CPrefs::MailHeaderDisplay,    STRINGLIST,    eLongType,    res_StringsLong, 34,
  436.         "mail.show_headers"},
  437.     {    CPrefs::NewsHeaderDisplay,    STRINGLIST,    eLongType,    res_StringsLong, 35,
  438.         "news.show_headers"},
  439.     {    CPrefs::AutoSaveTimeDelay,    STRINGLIST,    eLongType,    res_StringsLong, 36,
  440.         "editor.auto_save_delay"},
  441. #ifdef FORTEZZA
  442.     {    CPrefs::FortezzaTimeout,    STRINGLIST,    eLongType,    res_StringsLong, 37,
  443.         "security.fortezza_lifetime" },
  444. #endif
  445.  
  446. // Colors
  447.     {    CPrefs::Black,                NOTSAVED,    eColorType, 0, 1},
  448.     {    CPrefs::White,                NOTSAVED,    eColorType, 0, 1},
  449.     {    CPrefs::Blue,                NOTSAVED,    eColorType, 0, 1},
  450.     {    CPrefs::Magenta,            NOTSAVED,    eColorType, 0, 1},
  451.     {    CPrefs::WindowBkgnd,        NOTSAVED,    eColorType, 0, 1},    // --was res_StringsColor, 1
  452.     {    CPrefs::Anchor,                STRINGLIST, eColorType, res_StringsColor, 2,
  453.         "browser.anchor_color"},
  454.     {    CPrefs::Visited,            STRINGLIST, eColorType, res_StringsColor, 3,
  455.         "browser.visited_color"},
  456.     {    CPrefs::TextFore,            STRINGLIST,    eColorType, res_StringsColor, 4,
  457.         "browser.foreground_color"},
  458.     {    CPrefs::TextBkgnd,            STRINGLIST, eColorType, res_StringsColor, 5,
  459.         "browser.background_color"},
  460.     {    CPrefs::EditorText,            STRINGLIST,    eColorType, res_StringsColor, 6,
  461.         "editor.text_color"},
  462.     {    CPrefs::EditorLink,            STRINGLIST,    eColorType, res_StringsColor, 7,
  463.         "editor.link_color"},
  464.     {    CPrefs::EditorActiveLink,    STRINGLIST,    eColorType, res_StringsColor, 8,
  465.         "editor.active_link_color"},
  466.     {    CPrefs::EditorFollowedLink,    STRINGLIST,    eColorType, res_StringsColor, 9,
  467.         "editor.followed_link_color"},
  468.     {    CPrefs::EditorBackground,    STRINGLIST,    eColorType, res_StringsColor, 10,
  469.         "editor.background_color"},
  470.     {     CPrefs::Citation,            STRINGLIST,    eColorType,    res_StringsColor, 11,
  471.         "mail.citation_color"},
  472. // Print record
  473.     {    CPrefs::PrintRecord,        PRINTRECORD, ePrintRecordType, res_PrintRecord, 0 },
  474. // Terminator
  475.     {    CPrefs::LastPref,            NOTSAVED,    eNoType, 0,    0}
  476. };
  477.  
  478. // 
  479. //    Class variables
  480. //
  481. RGBColor *     CPrefs::sColors = NULL;
  482. CFolderSpec ** CPrefs::sFileIDs = NULL;
  483. THPrint        CPrefs::sPrintRec = NULL;
  484. CMimeList     CPrefs::sMimeTypes;
  485. char *        CPrefs::sCachePath = NULL;
  486.  
  487. FSSpec        CPrefs::sTemporaryFolder;
  488. Boolean        CPrefs::sRealTemporaryFolder = false;
  489. Boolean        CPrefs::sViewSourceInline = true;
  490. // 0 = no user preference file
  491. // 3 = preferences in resource fork
  492. // 4 = preferences in data fork
  493. short        CPrefs::sPrefFileVersion = 3;
  494.  
  495. //
  496. // Static variables
  497. //
  498.  
  499. // Preference file related
  500. static        LFile * sPrefFile = NULL;
  501. static        short     sPrefFileResID = refNum_Undefined;
  502. static        short    sAppFileResID = refNum_Undefined;
  503. static        Boolean    sReading = FALSE;     // Are we reading the prefs right now?
  504. static        Boolean sDirty = FALSE;        
  505. static        Boolean sDirtyOnRead = FALSE;    // Used to signal saving of preferences 
  506.                                             // if we need to touch them while reading
  507. // 
  508. // Utility routines
  509. //
  510. static UInt32 CountPrefsOfType(PrefType type);
  511. static LFile* GetFileForPreferences();
  512. /*static*/ Boolean FindDefaultPreferencesFolder( FSSpec& prefFolder, short folderNameID,
  513.     Boolean createIt, Boolean resolveIt = true );
  514. static OSErr AssertPrefsFileOpen(Int16 privileges);
  515. static LO_Color MakeLOColor( const RGBColor& rgbColor );
  516. static OSErr AssurePreferencesSubfolder(pref_Strings whichFolder, FSSpec & folderSpec);
  517.  
  518. // Counts how many preferences of particular type do we have
  519. UInt32 CountPrefsOfType(PrefType type)
  520. {
  521.     UInt32 howMany = 0;
  522.     int i = 0;
  523.     while(prefLoc[i].prefType != eNoType)
  524.         if (prefLoc[i++].prefType == type)
  525.             howMany++;
  526.     return howMany;
  527. }
  528.  
  529. // FindDefaultPreferencesFolder searches the disk for a preferences folder.
  530. // If it does not find one, it tries to create it.
  531. // It returns false upon complete failure (could not find or create)
  532. // Folder lookup sequence: Preferences, Home directory, Desktop
  533. // Algorithm:
  534. // Look for a folder in folder lookup sequence.
  535. // If not found try to create it in the same sequence.
  536. Boolean FindDefaultPreferencesFolder( FSSpec& prefFolder, short folderNameID,
  537.     Boolean createIt, Boolean resolveIt )
  538. {
  539.     short     prefRefNum, deskRefNum;
  540.     long      prefDirID, deskDirID;
  541.     FSSpec netscapeFolder = CPrefs::GetFilePrototype(CPrefs::NetscapeFolder);
  542.  
  543.     OSErr err = FindFolder( kOnSystemDisk, kPreferencesFolderType, kCreateFolder, &prefRefNum, &prefDirID );// Get Pref directory
  544.     OSErr err2 = FindFolder( kOnSystemDisk, kDesktopFolderType, kCreateFolder, &deskRefNum, &deskDirID );
  545.     
  546.     // Ñ check for presence of MCC folder╔
  547.     Boolean foundFolder = FALSE;
  548.     CStr255 folderName;
  549.     GetIndString( folderName, 300, folderNameID );
  550.     LString::CopyPStr( folderName, prefFolder.name, 32 );
  551.  
  552.     // Ñ in the Preferences folder
  553.     if ( !foundFolder &&  ( err == noErr ) &&
  554.         ( CFileMgr::FindWFolderInFolder(    prefRefNum, prefDirID,
  555.                                             folderName,
  556.                                             &prefFolder.vRefNum, &prefFolder.parID) == noErr ) )
  557.         foundFolder = TRUE;
  558.  
  559.     // Ñ╩in the applications folder
  560.     if ( !foundFolder && 
  561.          ( CFileMgr::FindWFolderInFolder(    netscapeFolder.vRefNum, netscapeFolder.parID,
  562.                                             folderName,
  563.                                             &prefFolder.vRefNum, &prefFolder.parID) == noErr ) )
  564.         foundFolder = TRUE;
  565.  
  566.     // Ñ╩and on the desktop
  567.     if ( ( !foundFolder ) && ( err2 == noErr ) && 
  568.         ( CFileMgr::FindWFolderInFolder(    deskRefNum, deskDirID,
  569.                                             folderName,
  570.                                             &prefFolder.vRefNum, &prefFolder.parID) == noErr ) )
  571.         foundFolder = TRUE;
  572.  
  573.     // Ñ╩create a folder if one does not exist. Go in Folder lookup sequence
  574.     if ( !foundFolder && createIt )    
  575.     {
  576.         // Ñ get the name of the folder out of resources
  577.         CStr255 folderName;
  578.         GetIndString( folderName, 300, folderNameID );
  579.         OSErr createError;
  580.  
  581.         // Ñ╩try the Preferences folder
  582.         createError = CFileMgr::CreateFolderInFolder( prefRefNum, prefDirID,
  583.                                             folderName, &prefFolder.vRefNum, &prefFolder.parID);
  584.  
  585.         if ( createError == noErr )
  586.             foundFolder = TRUE;
  587.         else    
  588.         {
  589.             // Ñ╩try the application's folder
  590.             createError = CFileMgr::CreateFolderInFolder( netscapeFolder.vRefNum, netscapeFolder.parID,
  591.                                             folderName, &prefFolder.vRefNum, &prefFolder.parID);            
  592.             if ( createError == noErr )
  593.                 foundFolder = TRUE;
  594.             else
  595.             {
  596.                 // Ñ try the Desktop
  597.                 createError = CFileMgr::CreateFolderInFolder(deskRefNum, deskDirID,
  598.                                             folderName, &prefFolder.vRefNum, &prefFolder.parID);            
  599.                 if ( createError == noErr )
  600.                     foundFolder = TRUE;
  601.                 else
  602.                     foundFolder = FALSE;
  603.             }
  604.         }
  605.     }
  606.  
  607.     if (foundFolder && resolveIt)
  608.         CFileMgr::FolderSpecFromFolderID(prefFolder.vRefNum, prefFolder.parID, prefFolder);
  609.  
  610.     return foundFolder;
  611. }
  612.  
  613. inline Boolean CPrefs::IsNewPrefFormat(short id)
  614. {
  615.     return prefLoc[id].prefName != nil;
  616. }
  617.  
  618. // Returns LFile for the preferences
  619. // File might not exist
  620. LFile* GetFileForPreferences()
  621. {
  622.     FSSpec        prefFileSpec;
  623.     
  624.     // Ñ╩get the default preferences file name from the application rsrc fork
  625.     ::GetIndString( prefFileSpec.name, 300, prefFileName );
  626.     
  627.     if ( prefFileSpec.name[0] > 31 )
  628.         prefFileSpec.name[0] = 31;
  629.         
  630.     FSSpec folderSpec = CPrefs::GetFilePrototype(CPrefs::MainFolder);
  631.     prefFileSpec.vRefNum = folderSpec.vRefNum;
  632.     prefFileSpec.parID = folderSpec.parID;
  633.  
  634.     CPrefs::sPrefFileVersion = CFileMgr::FileExists(prefFileSpec) ? 3 : 0;
  635.     
  636.     // Ñ return a fully specified LFile
  637.     return new LFile( prefFileSpec );
  638. }
  639.  
  640. // Creates the file if it does not exist
  641. static OSErr AssertPrefsFileOpen(Int16 privileges)
  642. {
  643.     Try_
  644.     {
  645.         ThrowIfNil_(sPrefFile);
  646.         Try_
  647.         {
  648.             sPrefFile->OpenResourceFork(privileges);
  649.         }
  650.         Catch_(inErr)
  651.         {
  652.             // Create the resource fork if it doesn't exist
  653.             if (inErr == fnfErr || inErr == eofErr) {
  654.                 sPrefFile->CreateNewFile(emSignature, emPrefsType);
  655.                 
  656.                 sPrefFile->OpenResourceFork(privileges);
  657.             }
  658.         
  659.             // Non-fatal error. We are trying to open prefs twice in a row
  660.             else if (!((inErr == opWrErr) &&
  661.                     (sPrefFile->GetResourceForkRefNum() != refNum_Undefined)))
  662.                 Throw_(inErr);
  663.         }
  664.         EndCatch_
  665.         sPrefFileResID = sPrefFile->GetResourceForkRefNum();
  666.     }
  667.     Catch_(inErr)
  668.     {
  669.         return inErr;
  670.     }
  671.     EndCatch_
  672.     return noErr;
  673. }
  674.  
  675. static void ClosePrefsFile()
  676. {
  677.     Try_
  678.     {
  679.         if (sPrefFile)
  680.         {
  681.             if (sPrefFile->GetResourceForkRefNum() != refNum_Undefined)
  682.                 sPrefFile->CloseResourceFork();
  683.             if (sPrefFile->GetDataForkRefNum() != refNum_Undefined)
  684.                 sPrefFile->CloseDataFork();
  685.         }
  686.     }
  687.     Catch_(inErr)
  688.     {
  689.         Assert_(FALSE);
  690.     }
  691.     EndCatch_
  692.     sPrefFileResID = refNum_Undefined;
  693.     
  694.     //
  695.     // Now that the prefs are closed, make sure we╒re
  696.     // not using some random file (like a plug-in).
  697.     //
  698.     CPrefs::UseApplicationResFile();        
  699. }
  700.  
  701.  
  702. #define NON_EXISTENT_NAME        "\pNONEXISTENTsj8432903849"
  703.  
  704. // Ñ Makes sure that the folder with a given spec exists inside preferences.
  705. //   if it is not found, it creates one.
  706. static OSErr AssurePreferencesSubfolder(pref_Strings whichFolder, FSSpec & folderSpec)
  707. {
  708.     FSSpec mainSpec = CPrefs::GetFilePrototype(CPrefs::MainFolder);
  709.     // Find a folder. Create one if necessary
  710.     ::GetIndString( folderSpec.name, 300, whichFolder );
  711.     OSErr err = noErr;
  712.     if ( CFileMgr::FindWFolderInFolder(mainSpec.vRefNum, mainSpec.parID,
  713.                                     folderSpec.name, 
  714.                                     &folderSpec.vRefNum, &folderSpec.parID) != noErr )
  715.     // Not found, must create it
  716.         err = CFileMgr::CreateFolderInFolder( mainSpec.vRefNum, mainSpec.parID,
  717.                                      folderSpec.name, 
  718.                                      &folderSpec.vRefNum, &folderSpec.parID );
  719.         if ( err != noErr )    // Also try application folder for lab settings
  720.         {
  721.             mainSpec = CPrefs::GetFilePrototype( CPrefs::NetscapeFolder );
  722.             err = CFileMgr::FindWFolderInFolder( mainSpec.vRefNum, mainSpec.parID,
  723.                                     folderSpec.name, 
  724.                                     &folderSpec.vRefNum, &folderSpec.parID );
  725.             if ( err != noErr )
  726.                 err = CFileMgr::CreateFolderInFolder( mainSpec.vRefNum, mainSpec.parID,
  727.                                      folderSpec.name, 
  728.                                      &folderSpec.vRefNum, &folderSpec.parID );
  729.         }
  730.         err = CFileMgr::FolderSpecFromFolderID( folderSpec.vRefNum, folderSpec.parID, folderSpec );
  731.     return err;
  732. }
  733.  
  734. static CStr255 BuildProxyString(CStr255 host, CStr255 port)
  735. {
  736.     CStr255 ret = host;
  737.     if ((host.Length() > 0) && (port.Length() > 0))
  738.     {
  739.         ret += ":";
  740.         ret += port;
  741.     }
  742.     return ret;
  743. }
  744.  
  745. static LO_Color MakeLOColor( const RGBColor& rgbColor )
  746. {
  747.     LO_Color        temp;
  748.     temp.red = rgbColor.red >> 8;
  749.     temp.green = rgbColor.green >> 8;
  750.     temp.blue = rgbColor.blue >> 8;
  751.     return temp;
  752. }
  753.  
  754. // Returns TRUE if resource existed
  755. // If it does not exist, creates a resource of 0 length
  756. static Boolean AssertResourceExist(ResType type, short id)
  757. {
  758.     Handle r = ::Get1Resource(type, id);
  759.     if (r == NULL)
  760.     {
  761.         Handle h = ::NewHandle(0);
  762.         ThrowIfNil_(h);
  763.         ::AddResource(h, type, id, CStr255::sEmptyString);
  764.         ThrowIfResError_();
  765.         
  766.         SInt8 flags = ::HGetState(h);
  767.         ::HNoPurge(h);
  768.         
  769.         ::SetResAttrs(h, ::GetResAttrs(h) | resPurgeable);    // Pref resources are purgeable
  770.         if (type == STRINGLIST)
  771.         {
  772.             CStringListRsrc stringList(id);
  773.             stringList.ClearAll();
  774.         }
  775.         ::HSetState(h, flags);
  776.         
  777.         return FALSE;
  778.     }
  779.     else
  780.         return TRUE;
  781. }
  782.  
  783. /*****************************************************************************
  784.  * struct CFolderSpec
  785.  * Contains specs for the folder and a prototype spec for the file to be 
  786.  * created inside this folder
  787.  *****************************************************************************/ 
  788.  
  789. CFolderSpec::CFolderSpec()
  790. {
  791.     fFolder.vRefNum = fFolder.parID = refNum_Undefined;
  792.     fFilePrototype.vRefNum = fFilePrototype.parID = refNum_Undefined;
  793. }
  794.  
  795. // Sets the specs for this folder. Must figure out the prototype file specs too
  796. OSErr CFolderSpec::SetFolderSpec(FSSpec newSpec, int folderID)
  797.     /*
  798.         This routine is called for two different sorts of folders, those whose locations are saved in
  799.         the preferences, and those that are not.  For the former, |newSpec| is constructed from the saved
  800.         location.  For the latter, it is uninitialized.
  801.     */
  802. {
  803.     FSSpec        debugSpec;
  804.     OSErr        settingError;
  805.     settingError = FSMakeFSSpec( newSpec.vRefNum, newSpec.parID, newSpec.name, &debugSpec);
  806.  
  807.     if ( settingError != noErr )
  808.     {
  809.         sDirtyOnRead = TRUE;
  810.         Try_
  811.         {
  812.             switch ( (CPrefs::PrefEnum)folderID )
  813.             {
  814.                 case CPrefs::DownloadFolder:
  815.                     ThrowIfOSErr_( FindFolder( kOnSystemDisk, kDesktopFolderType,
  816.                         kCreateFolder, &newSpec.vRefNum, &newSpec.parID ));
  817.                     ThrowIfOSErr_( CFileMgr::FolderSpecFromFolderID(newSpec.vRefNum, newSpec.parID, newSpec));
  818.                 break;
  819.                 case CPrefs::NewsFolder:
  820.                 {
  821.                     // OSErr err = AssurePreferencesSubfolder(newsFolderName, newSpec);
  822.                     OSErr err = fnfErr;        // Brutal hard coded err for a world without mail/news
  823.                     if ( err != noErr )
  824.                     {
  825.                         fFolder.vRefNum = fFolder.parID = fFilePrototype.vRefNum = fFilePrototype.parID = 0;
  826.                         return err;
  827.                     }
  828.                 }
  829.                 break;    
  830.                 case CPrefs::SecurityFolder:
  831.                 {
  832.                     OSErr err = AssurePreferencesSubfolder(securityFolderName, newSpec);
  833.                     if ( err != noErr )
  834.                     {
  835.                         fFolder.vRefNum = fFolder.parID = fFilePrototype.vRefNum = fFilePrototype.parID = 0;
  836.                         return err;
  837.                     }
  838.                 }
  839.                 break;    
  840.                 case CPrefs::DiskCacheFolder:
  841.                     // Caching folder. By default it is inside the main folder.
  842.                 {
  843.                     OSErr err = AssurePreferencesSubfolder(cacheFolderName, newSpec);
  844.                     if ( err != noErr )
  845.                     {
  846.                         fFolder.vRefNum = fFolder.parID = fFilePrototype.vRefNum = fFilePrototype.parID = 0;
  847.                         return err;
  848.                     }
  849.                 }
  850.                 break;
  851.                 
  852.                 case CPrefs::SARCacheFolder:
  853.                     // Archive Cache folder. By default it is inside the main folder.
  854.                 {
  855.                     OSErr err = AssurePreferencesSubfolder(sarCacheFolderName, newSpec);
  856.                     if ( err != noErr )
  857.                     {
  858.                         fFolder.vRefNum = fFolder.parID = fFilePrototype.vRefNum = fFilePrototype.parID = 0;
  859.                         return err;
  860.                     }
  861.                 }
  862.                 break;
  863.                 
  864.                 case CPrefs::MailFolder:
  865.                 {
  866.                     // OSErr err = AssurePreferencesSubfolder(mailFolderName, newSpec);
  867.                     OSErr err = fnfErr;        // Brutal hard coded err for a world without mail/news
  868.                     if ( err != noErr )
  869.                     {
  870.                             fFolder.vRefNum = fFolder.parID = fFilePrototype.vRefNum = fFilePrototype.parID = 0;
  871.                             return err;
  872.                     }
  873.                 }
  874.                 break;
  875.                 case CPrefs::NetHelpFolder:
  876.                 {
  877.                         /*
  878.                             [scc:] Essentially this same code appears in uapp.cp for resolving the "Essential Files" folder.
  879.                             It should be broken out into a separate static member function of |CFileMgr| a la FindWFolderInFolder.
  880.                         */
  881.               FSSpec    netscapeFolderSpec = CPrefs::GetFolderSpec(CPrefs::NetscapeFolder);
  882.                         // Build a partial path to the guts folder starting from a folder we know (the Netscape folder)
  883.               Str255    partialPath;
  884.  
  885.                     {
  886.                             // Get the name of the guts folder
  887.                         Str255 helpFolderName;
  888.                         GetIndString(helpFolderName, 300, nethelpFolderName);    
  889.  
  890.                             // partialPath = ":" + netscapeFolderSpec.name + ":" + gutsFolderName;
  891.                             //    ( this may _look_ cumbersome, but it's really the most space and time efficient way to catentate 4 pstrings )
  892.                         int dest=0;
  893.                         partialPath[++dest] = ':';
  894.                         for ( int src=0; src<netscapeFolderSpec.name[0]; )
  895.                             partialPath[++dest] = netscapeFolderSpec.name[++src];
  896.                         partialPath[++dest] = ':';
  897.                         for ( int src=0; src<helpFolderName[0]; )
  898.                             partialPath[++dest] = helpFolderName[++src];
  899.                         partialPath[0] = dest;
  900.                     }
  901.  
  902.                         // Use the partial path to construct an FSSpec identifying the required guts folder
  903.                     if ( FSMakeFSSpec(netscapeFolderSpec.vRefNum, netscapeFolderSpec.parID, partialPath, &newSpec) == noErr )
  904.                         {    // Ensure that the folder exists (even if pointed to by an alias) and actually _is_ a folder
  905.                             Boolean targetIsFolder, targetWasAliased;
  906.                             ResolveAliasFile(&newSpec, true, &targetIsFolder, &targetWasAliased);
  907.                         }
  908.                 }
  909.                 break;
  910.                 case CPrefs::MailCCFile:
  911.                 {    
  912.                     CStr255 defaultName;
  913.                     newSpec = CPrefs::GetFilePrototype(CPrefs::MailFolder);
  914.                     GetIndString( defaultName, 300, mailCCfile );
  915.                     LString::CopyPStr(defaultName, newSpec.name, 32);
  916.                 }
  917.                 break;
  918.                 case CPrefs::NewsCCFile:
  919.                 {    
  920.                     CStr255 defaultName;
  921.                     newSpec = CPrefs::GetFilePrototype(CPrefs::MailFolder);
  922.                     GetIndString( defaultName, 300, newsCCfile );
  923.                     LString::CopyPStr(defaultName, newSpec.name, 32);
  924.                 }
  925.                 break;
  926.                 case CPrefs::MainFolder:    // These are all created dynamically            
  927.                 case CPrefs::NetscapeFolder:
  928.                 case CPrefs::RequiredGutsFolder:
  929.                 return noErr;
  930.             }
  931.         }
  932.         Catch_( err )
  933.         {    // Not much of an error handling, just assign 0 to all, which places files in Netscape folder
  934.             newSpec.vRefNum = 0;
  935.             newSpec.parID = 0;
  936.         }
  937.         EndCatch_
  938.     }
  939.     fFolder = newSpec;    // Assign the spec
  940.     
  941.     // New folder is the parent of the prototype file. Find the file ID of the new folder
  942.     // and make it a parent of the prototype file
  943.     (CStr63&)fFilePrototype.name = fFolder.name;
  944.     CInfoPBRec cinfo;
  945.     DirInfo    *dipb=(DirInfo *)&cinfo;
  946.     dipb->ioNamePtr = (StringPtr)&fFilePrototype.name;
  947.     dipb->ioVRefNum = fFolder.vRefNum;
  948.     dipb->ioFDirIndex = 0;
  949.     dipb->ioDrDirID = fFolder.parID;
  950.     OSErr err = PBGetCatInfoSync(&cinfo);
  951.     fFilePrototype.name[0] = 0; // there are places where a path is made from the raw prototype!
  952.     if (err == noErr)
  953.     {
  954.         fFilePrototype.vRefNum = dipb->ioVRefNum;
  955.         fFilePrototype.parID = dipb->ioDrDirID;
  956.     }
  957.     else
  958.     {
  959.         fFilePrototype.vRefNum = 0;
  960.         fFilePrototype.parID = 0;
  961.     }
  962.     return settingError;
  963. }
  964.  
  965. Boolean CFolderSpec::Exists()
  966. {
  967.     CStr63        name;
  968.     CStr63        doesntExist( NON_EXISTENT_NAME );
  969.     
  970.     name = fFolder.name;
  971.     
  972.     return ( name != doesntExist );
  973. }
  974.  
  975. //----------------------------------------------------------------------------------------
  976. void CPrefs::Initialize()
  977. // Initialize all statics
  978. // This must be called before any other preference routines.
  979. // OK, so would somebody please add a comment as to why this can't be done in the
  980. // constructor?
  981. //----------------------------------------------------------------------------------------
  982. {
  983.     UInt32 howMany = CountPrefsOfType(eFileSpecType);
  984.     sFileIDs = (CFolderSpec **)XP_CALLOC(1, howMany * sizeof(CFolderSpec *));
  985.     ThrowIfNil_( sFileIDs );
  986.     for (int i=0; i<howMany; i++)
  987.         sFileIDs[i] = new CFolderSpec;
  988.  
  989.     howMany = CountPrefsOfType(eColorType);
  990.     sColors = (RGBColor *)XP_CALLOC(1, howMany * sizeof(RGBColor));
  991.     ThrowIfNil_( sColors );
  992.     
  993.     fCharSetFonts = new LArray( sizeof( CCharSet ) );
  994.     ThrowIfNil_( fCharSetFonts );
  995.     
  996.  
  997.     // We will attempt to use the system's temporary items folder
  998.     // for all of our temp files.
  999.  
  1000.     // The folder is invisible to the user and is automatically 
  1001.     // emptied on system startup.
  1002.     
  1003.     // On entry, the static member sRealTemporaryFolder is false.  We only set it to
  1004.     // true if the system temp folder is satisfactory.  Otherwise, the download folder
  1005.     // will be used.
  1006.  
  1007.     if (noErr != ::FindFolder(
  1008.          kOnSystemDisk, 
  1009.         kTemporaryFolderType, 
  1010.         kCreateFolder, 
  1011.         &sTemporaryFolder.vRefNum, 
  1012.         &sTemporaryFolder.parID))
  1013.     {
  1014.         // Note: sTemporaryFolder is not the spec of anything, it is a prototype
  1015.         // for a file WITHIN the temporary folder.
  1016.         return;
  1017.     }
  1018.     
  1019.     // Bug #105473
  1020.     //     Customer running "At Ease" cannot use mail because the temporary items folder
  1021.     //    does not have write access.  So check for write access by trying to create a file.
  1022.     //    If the attempt fails, fall back on our "Download folder" strategy.
  1023.     //        - jrm 98/02/10
  1024.     FSSpec trialSpec = sTemporaryFolder;
  1025.     *(CStr63*)&trialSpec.name = "Foobar";
  1026.     if (noErr != ::FSpCreate(&trialSpec, 'GDAY', 'GDAY', 0))
  1027.         return;
  1028.     // Well, if it passed that test, it's hunky dory.  Clean up, and then record the fact
  1029.     // that the system temp folder is the one to use.
  1030.     ::FSpDelete(&trialSpec);
  1031.     sRealTemporaryFolder = true;
  1032. }
  1033.  
  1034. //----------------------------------------------------------------------------------------
  1035. FSSpec CPrefs::GetTempFilePrototype()
  1036. //    Just as well the ::FindFolder() call above seldom fails. In fact, many clients of this routine
  1037. //    are expecting it to return the temporary folder PROTOTYPE, not the spec.  This
  1038. //    was what was happening if sRealTemporaryFolder was true.  Thus, if we fall back on
  1039. //    the download folder, we need to have the prototype, and not the spec of the folder.
  1040. //    As of 98/02/11, there was confusion on this point.  Fortunately, all of our routines
  1041. //    that convert a spec into a path will tolerate a "prototype" whose name is set to
  1042. //    an empty string.  That's why callers who were using the result this way were succeeding
  1043. //    for the temporary folder case (the string was empty) but in the download-folder case we were
  1044. //    previously returning GetFolderSpec(DownloadFolder), which was wrong.  It failed, in particular,
  1045. //    when the download folder was the root of a volume.
  1046. //----------------------------------------------------------------------------------------
  1047. {
  1048.     if (sRealTemporaryFolder)
  1049.         return sTemporaryFolder;
  1050.     return GetFilePrototype(MainFolder);
  1051. }
  1052.  
  1053. //----------------------------------------------------------------------------------------
  1054. int CPrefs::ColorPrefCallback(const char */*prefString*/, void */*data*/)
  1055. //----------------------------------------------------------------------------------------
  1056. {
  1057.     LO_Color loColor = MakeLOColor(GetColor(TextFore));
  1058.     LO_SetDefaultColor( LO_COLOR_FG , loColor.red, loColor.green, loColor.blue);
  1059.     loColor = MakeLOColor(GetColor(TextBkgnd));
  1060.     LO_SetDefaultColor( LO_COLOR_BG, loColor.red, loColor.green, loColor.blue);
  1061.     loColor = MakeLOColor(GetColor(Anchor));
  1062.     LO_SetDefaultColor( LO_COLOR_LINK, loColor.red, loColor.green, loColor.blue);
  1063.     loColor = MakeLOColor(GetColor(Visited));
  1064.     LO_SetDefaultColor( LO_COLOR_VLINK, loColor.red, loColor.green, loColor.blue);
  1065.     LO_SetUserOverride(!GetBoolean(UseDocumentColors));
  1066.  
  1067.     return 0;    // insert complaint about this later    
  1068. }
  1069.  
  1070. int
  1071. CPrefs::FSSpecPrefCallback(const char *prefString, void *enumValue)
  1072. {
  1073.     PrefEnum    thePref = (PrefEnum)enumValue;
  1074.  
  1075.     AliasHandle aliasH = NULL;
  1076.     int size;
  1077.     void* alias;
  1078.     if (PREF_CopyBinaryPref(prefString, &alias, &size ) == 0)
  1079.     {
  1080.         PtrToHand(alias, &(Handle)aliasH, size);
  1081.         XP_FREE(alias);
  1082.     }
  1083.  
  1084.     FSSpec    target;
  1085.     Boolean    wasChanged;
  1086.     OSErr    iErr = ResolveAlias(nil, aliasH, &target, &wasChanged);
  1087.     DisposeHandle((Handle)aliasH);
  1088.     SetFolderSpec(target, thePref);
  1089.     return 0;    // You don't even want to know my opinion of this!
  1090. }
  1091.  
  1092. void
  1093. CPrefs::RegisterPrefCallbacks()
  1094. {
  1095.     PREF_RegisterCallback(    "browser.download_directory", FSSpecPrefCallback,
  1096.                             (void *)DownloadFolder);
  1097. //    PREF_RegisterCallback("", FSSpecPrefCallback, (void *)NetscapeFolder);
  1098. //    PREF_RegisterCallback("", FSSpecPrefCallback, (void *)MainFolder);
  1099. //    PREF_RegisterCallback("", FSSpecPrefCallback, (void *)UsersFolder);
  1100.     PREF_RegisterCallback(    "browser.cache.directory", FSSpecPrefCallback,
  1101.                             (void *)DiskCacheFolder);
  1102.     PREF_RegisterCallback(    "mail.signature_file", FSSpecPrefCallback,
  1103.                             (void *)SignatureFile);
  1104. //    PREF_RegisterCallback(    "browser.gif_backdrop_file", FSSpecPrefCallback,
  1105. //                            (void *)GIFBackdropFile);
  1106.     PREF_RegisterCallback(    "mail.directory", FSSpecPrefCallback,
  1107.                             (void *)MailFolder);
  1108.     PREF_RegisterCallback(    "news.directory", FSSpecPrefCallback,
  1109.                             (void *)NewsFolder);
  1110. //    PREF_RegisterCallback("", FSSpecPrefCallback, (void *)SecurityFolder);
  1111.     PREF_RegisterCallback(    "mail.cc_file", FSSpecPrefCallback,
  1112.                             (void *)MailCCFile);
  1113.     PREF_RegisterCallback(    "news.cc_file", FSSpecPrefCallback,
  1114.                             (void *)NewsCCFile);
  1115.     PREF_RegisterCallback(    "editor.html_editor", FSSpecPrefCallback,
  1116.                             (void *)HTMLEditor);
  1117.     PREF_RegisterCallback(    "editor.image_editor", FSSpecPrefCallback,
  1118.                             (void *)ImageEditor);
  1119. //    PREF_RegisterCallback("", FSSpecPrefCallback, (void *)RequiredGutsFolder);
  1120. //    PREF_RegisterCallback("", FSSpecPrefCallback, (void *)SARCacheFolder);
  1121. //    PREF_RegisterCallback("", FSSpecPrefCallback, (void *)NetHelpFolder);
  1122.  
  1123.     // register color pref callbacks too
  1124.     PREF_RegisterCallback("browser.foreground_color", ColorPrefCallback, nil);
  1125.     PREF_RegisterCallback("browser.anchor_color", ColorPrefCallback, nil);
  1126.     PREF_RegisterCallback("browser.visited_color", ColorPrefCallback, nil);
  1127.     PREF_RegisterCallback("browser.background_color", ColorPrefCallback, nil);
  1128.     PREF_RegisterCallback("browser.use_document_colors", ColorPrefCallback, nil);
  1129. }
  1130.  
  1131. // Returns true iff startup should be aborted
  1132. CPrefs::PrefErr CPrefs::DoRead( LFile * file, short fileType )
  1133. {
  1134.     if ( sPrefFile )
  1135.     {
  1136.         ErrorManager::PlainAlert( mPREFS_CANNOT_OPEN_SECOND_ALERT );
  1137.         return CPrefs::eAbort;
  1138.     }
  1139.     sPrefFile = file;
  1140.     
  1141.     CPrefs::PrefErr result = InitPrefsFolder( fileType );
  1142.     if ( result == CPrefs::eAbort )
  1143.         return result;
  1144.     
  1145.     // fix-me must handle a return code here (if it returns false, we need to quit or do
  1146.     // something intelligent
  1147.         
  1148.     if ( !sPrefFile ) {
  1149.         sPrefFile = GetFileForPreferences();
  1150.     }
  1151.     
  1152.     FSSpec prefSpec;
  1153.     sPrefFile->GetSpecifier(prefSpec);
  1154.     char* prefFile = CFileMgr::PathNameFromFSSpec(prefSpec, true);
  1155.     
  1156.     // Note: we call PREF_Init(NULL) in main() in uapp.cp;
  1157.     // the call below does not re-initialize but loads the user prefs file.
  1158.     if ( PREF_Init(prefFile) == JS_TRUE ) {
  1159.         sPrefFileVersion = 4;
  1160.     }
  1161.     XP_FREE(prefFile);
  1162.         
  1163.     // Read optional profile.cfg (per-profile configuration) file
  1164.     FSSpec profileConfig;
  1165.     profileConfig.vRefNum = prefSpec.vRefNum;
  1166.     profileConfig.parID = prefSpec.parID;
  1167.     LString::CopyPStr("\pprofile.cfg", profileConfig.name, 32);
  1168.     if (CFileMgr::FileExists(profileConfig)) {
  1169.         PREF_ReadLockFile( CFileMgr::PathNameFromFSSpec(profileConfig, true) );
  1170.     }
  1171.     
  1172.     // Read the lock/config file, looking in both the 
  1173.     // Users folder and the Essential Files folder
  1174.     Boolean lockLoaded = false;
  1175.     FSSpec lockSpec = CPrefs::GetFilePrototype(CPrefs::RequiredGutsFolder);        
  1176.     GetIndString(lockSpec.name, 300, configFile);
  1177.     
  1178.     if (!CFileMgr::FileExists(lockSpec)) {
  1179.         lockSpec = CPrefs::GetFilePrototype(CPrefs::UsersFolder);
  1180.         GetIndString(lockSpec.name, 300, configFile);
  1181.     }
  1182.     if (CFileMgr::FileExists(lockSpec))
  1183.     {
  1184.         char* lockFile = CFileMgr::PathNameFromFSSpec(lockSpec, true);
  1185.     
  1186.         if (lockFile) {
  1187.             int lockErr = PREF_ReadLockFile(lockFile);
  1188.             lockLoaded = (lockErr == PREF_NOERROR);
  1189.             XP_FREE(lockFile);
  1190.             
  1191.             if (lockErr == PREF_BAD_LOCKFILE) {
  1192.                 CStr255 errStr;
  1193.                 GetIndString(errStr, CUserProfile::kProfileStrings, CUserProfile::kInvalidConfigFile);
  1194.                 ErrorManager::PlainAlert(errStr);
  1195.                 return eAbort;
  1196.             }
  1197.         }
  1198.     }
  1199.     
  1200.     // The presence of a 'Lock' application resource means
  1201.     // we should abort if the lock file failed to load
  1202.     if ( !lockLoaded && ::GetResource('Lock', 128) != nil )
  1203.     {
  1204.         CStr255 errStr;
  1205.         GetIndString(errStr, CUserProfile::kProfileStrings, CUserProfile::kConfigFileError);
  1206.         ErrorManager::PlainAlert(errStr);
  1207.         return eAbort;
  1208.     }
  1209.  
  1210.     OpenAnimationFile(lockSpec, profileConfig);
  1211.  
  1212.     ReadAllPreferences();
  1213.     
  1214.     {    // Connect to Internet Config, passing path of current
  1215.         // profile directory.  This allows each profile to
  1216.         // contain its own IC Preferences file.
  1217.         
  1218.         // We do not want a stupid break to source debugger every time
  1219.         StValueChanger<EDebugAction> okayToFail(gDebugThrow, debugAction_Nothing);
  1220.         CInternetConfigInterface::ConnectToInternetConfig(/*&prefSpec*/);
  1221.     }
  1222.     
  1223.     RegisterPrefCallbacks();
  1224.  
  1225.     // Ñ╩handle the upgrade path that involves us telling the user
  1226.     // that we're creating "Netscape Users", etc.
  1227.     // (I don't know why this is handled here)
  1228.     if ( result == eNeedUpgrade )
  1229.     {
  1230.         FSSpec        prefsFolder;
  1231.         FSSpec        oldPrefsFolder;
  1232.         ProfileErr    profResult;
  1233.         
  1234.         oldPrefsFolder = CPrefs::GetFolderSpec( CPrefs::MainFolder );
  1235.         profResult = CUserProfile::HandleUpgrade( prefsFolder, &oldPrefsFolder );
  1236.         if ( profResult == eOK || profResult == eRunAccountSetup )
  1237.         {
  1238.             // Ñ user OK'ed it, so we set the prefs folder to point to the new
  1239.             // place now
  1240.             CPrefs::SetFolderSpec( prefsFolder, CPrefs::MainFolder );
  1241.         }
  1242.         else
  1243.             // Ñ user chose to Quit
  1244.             return eAbort;
  1245.         if ( profResult == eRunAccountSetup )
  1246.             result = eRunAccountSetup;
  1247.     }
  1248.  
  1249.     // --EKit: Prevent failover if config is locked on auto-proxy
  1250.     if ( IsLocked(ProxyConfig) && GetLong(ProxyConfig) == PROXY_STYLE_AUTOMATIC ) {
  1251.         NET_SetNoProxyFailover();
  1252.     }
  1253.     
  1254.     return result;
  1255. }
  1256.  
  1257. void CPrefs::DoWrite()
  1258. {
  1259.     if (sPrefFile == NULL)
  1260.         sPrefFile = GetFileForPreferences();
  1261.     if (sPrefFile == NULL)
  1262.         return;
  1263.     if (!sDirty)
  1264.         return;
  1265.     WriteAllPreferences();
  1266. }
  1267.  
  1268. // Reads in all the preferences
  1269. void CPrefs::ReadAllPreferences()
  1270. {
  1271.     sReading = TRUE;
  1272.     Try_    
  1273.     {
  1274.         sDirtyOnRead = FALSE;
  1275.         AssertPrefsFileOpen(fsRdPerm);
  1276.  
  1277.         int i = FIRSTPREF;
  1278.         while(prefLoc[i].prefID != LastPref)
  1279.             ReadPreference((PrefEnum)i++);
  1280.         ReadMimeTypes();
  1281.         
  1282.         ReadCharacterEncodings();
  1283.         
  1284.         CNotifierRegistry::ReadProtocolHandlers();
  1285.         sDirty = sDirtyOnRead;
  1286.         // Needs to be done after all prefs have been read
  1287.         NET_SelectProxyStyle( (NET_ProxyStyle) GetLong( ProxyConfig) );
  1288.     }
  1289.     Catch_(inErr)
  1290.     {        
  1291.         ClosePrefsFile();
  1292.         sReading = FALSE;
  1293.         Throw_(inErr);
  1294.     }
  1295.     EndCatch_
  1296.     sReading = FALSE;
  1297.     ClosePrefsFile();
  1298. }
  1299.  
  1300. void CPrefs::WriteAllPreferences()
  1301. {
  1302.     Try_
  1303.     {
  1304.         ThrowIfOSErr_(AssertPrefsFileOpen(fsRdWrPerm));
  1305.  
  1306.         // --xp prefs 
  1307.         FSSpec prefSpec;
  1308.         sPrefFile->GetSpecifier(prefSpec);
  1309.         char* prefFile = CFileMgr::PathNameFromFSSpec(prefSpec, true);
  1310.         
  1311.         int err = PREF_SavePrefFileAs(prefFile);
  1312.         ThrowIfOSErr_(err);
  1313.         
  1314.         // -- WritePreference now skips all prefs except for print record 
  1315.         WritePreference( CPrefs::PrintRecord );
  1316.  
  1317.         CNotifierRegistry::WriteProtocolHandlers();
  1318.         AssertResourceExist(REVISION, REVISION_RES_ID);
  1319.         Handle    res = ::Get1Resource( REVISION, REVISION_RES_ID );
  1320.         if (res && *res)
  1321.         {
  1322.             SInt8 flags = ::HGetState(res);
  1323.             ::HNoPurge(res);
  1324.             if ((::GetHandleSize(res) < sizeof(long)) || (*(long *)*res != PREF_REVISION_NUMBER))
  1325.             {
  1326.                 ::SetHandleSize(res, sizeof(long));
  1327.                 ThrowIfMemError_();
  1328.                 *(long *)*res = PREF_REVISION_NUMBER;
  1329.                 ::ChangedResource(res);
  1330.                 ::WriteResource(res);
  1331.             }
  1332.             ::HSetState(res, flags);
  1333.         }
  1334.             
  1335.     }
  1336.     Catch_(inErr)
  1337.     {
  1338.         ClosePrefsFile();
  1339.         ErrorManager::PlainAlert( mPREFS_CANNOT_WRITE );
  1340.         ErrorManager::ErrorNotify(inErr, GetPString(THE_ERROR_WAS));
  1341.     }
  1342.     EndCatch_
  1343.     ClosePrefsFile();
  1344. }
  1345.  
  1346. // Gets the right resource
  1347. // First tries the pref file resource fork,
  1348. // On fail, try the application resource fork
  1349. // If they both fail, throw
  1350. void CPrefs::ReadPreference(short index)
  1351. {
  1352.     switch(prefLoc[index].resType)    {
  1353.     case NOTSAVED:
  1354.         InitializeUnsavedPref(index);
  1355.         break;
  1356.     case STRINGLIST:
  1357.         {
  1358.             CStr255 s;
  1359.             
  1360.             if ( sPrefFileVersion != 3 && IsNewPrefFormat(index) )
  1361.             {
  1362.                 // --xp prefs temp: Do this to send init prefs values to
  1363.                 // the right modules--
  1364.                 // to be REPLACED by modules initing own prefs via callbacks
  1365.                 PostInitializePref(prefLoc[index].prefID, true);
  1366.                 
  1367.                 return;
  1368.             }
  1369.             
  1370.             // Otherwise, read from old-format Prefs file
  1371.             if (UsePreferencesResFile())
  1372.             {
  1373.                 Handle stringListHandle = ::Get1Resource(STRINGLIST, prefLoc[index].resID);
  1374.                 
  1375.                 if (stringListHandle && *stringListHandle)
  1376.                 {
  1377.                     if (::GetHandleSize(stringListHandle) >= sizeof(short))
  1378.                     {
  1379.                         CStringListRsrc stringList(prefLoc[index].resID);
  1380.                         
  1381.                         if (stringList.CountStrings() >= prefLoc[index].refCon &&
  1382.                             prefLoc[index].refCon > 0)    // We are OK, we have a string
  1383.                         {
  1384.                             stringList.GetString(prefLoc[index].refCon, s);
  1385.                             goto postprocessstring;
  1386.                         }
  1387.                     }
  1388.                     else
  1389.                     {
  1390.                         ::RemoveResource(stringListHandle);
  1391.                         ::DisposeHandle(stringListHandle);
  1392.                     }
  1393.                 }
  1394.             }
  1395.             // drop through
  1396.             sDirtyOnRead = TRUE;
  1397.             
  1398.     postprocessstring:
  1399.             switch (prefLoc[index].prefType)    {
  1400.             case eStringType:
  1401.                 // Convert 3.0 ports from strings to ints
  1402.                 switch (prefLoc[index].prefID) {
  1403.                     case FTPProxyPort:
  1404.                     case GopherProxyPort:
  1405.                     case HTTPProxyPort:
  1406.                     case WAISProxyPort:
  1407.                     case SSLProxyPort:
  1408.                     case SOCKSPort:
  1409.                         Int32 value;
  1410.                         if (sscanf(s, "%ld", &value) == 1)
  1411.                             SetLong(value, prefLoc[index].prefID);
  1412.                         break;
  1413.                     
  1414.                     default:                    
  1415.                         SetString(s, prefLoc[index].prefID);
  1416.                 }
  1417.                 break;
  1418.             case eBooleanType:
  1419.                 Boolean bvalue;
  1420.                 if (strcasecomp(s, "FALSE") == 0)
  1421.                     bvalue = false;
  1422.                 else if (strcasecomp(s, "TRUE") == 0)
  1423.                     bvalue = true;
  1424.                 else
  1425.                     break;
  1426.                 switch (prefLoc[index].prefID) {
  1427.                     case EnableJava:
  1428.                     case EnableJavascript:
  1429.                         bvalue = ! bvalue;
  1430.                         break;
  1431.                     case UseInlineViewSource:
  1432.                         sViewSourceInline = bvalue;
  1433.                         break;
  1434.                 }
  1435.                 SetBoolean(bvalue, prefLoc[index].prefID);
  1436.                 break;
  1437.             case eLongType:
  1438.                 Int32 value;
  1439.                 if (sscanf(s, "%ld", &value) != 1)
  1440.                     break;
  1441.                     
  1442.                 // Magic conversions of 3.0 prefs to 4.0 units
  1443.                 if (prefLoc[index].prefID == PrintBackground)
  1444.                     SetBoolean (value != 0, PrintBackground);    // was a long, now a boolean
  1445.                 else {
  1446.                     switch (prefLoc[index].prefID) {
  1447.                         case DiskCacheSize:
  1448.                             value = value / DISK_CACHE_SCALE;    // was in bytes, now in K
  1449.                             break;
  1450.                         case BufferSize:
  1451.                             value = value * BUFFER_SCALE;        // was in K, now in bytes
  1452.                             break;
  1453.                         case MailHeaderDisplay:
  1454.                             switch (value) {                    // see msgprefs.cpp
  1455.                                 case SHOW_ALL_HEADERS:
  1456.                                     value = 2;
  1457.                                     break;
  1458.                                 case SHOW_SOME_HEADERS:
  1459.                                     value = 1;
  1460.                                     break;
  1461.                                 case SHOW_MICRO_HEADERS:
  1462.                                     value = 0;
  1463.                                     break;
  1464.                             }
  1465.                             break;
  1466.                     }
  1467.                     SetLong(value, prefLoc[index].prefID);
  1468.                 }
  1469.                 break;
  1470.             case eColorType:
  1471.                 long r,g,b;
  1472.                 RGBColor c;
  1473.                 if (sscanf(s, "%ld %ld %ld", &r, &g, &b) != 3)
  1474.                     break;
  1475.                 c.red = r;
  1476.                 c.green = g;
  1477.                 c.blue = b;
  1478.  
  1479.                 // Conversion from 3.0 colors. Use default color if
  1480.                 // the corresponding "use custom" box wasn't checked.
  1481.                 switch (prefLoc[index].prefID) {
  1482.                     case TextBkgnd:
  1483.                         if (GetLong(BackgroundColors) != CUSTOM_BACKGROUND)
  1484.                             c = GetColor(WindowBkgnd);
  1485.                         break;
  1486.                     case TextFore:
  1487.                         if (!GetBoolean(CustomTextColors))
  1488.                             c = GetColor(Black);
  1489.                         break;
  1490.                     case Anchor:
  1491.                         if (!GetBoolean(CustomLinkColors))
  1492.                             c = GetColor(Blue);
  1493.                         break;
  1494.                     case Visited:
  1495.                         if (!GetBoolean(CustomVisitedColors))
  1496.                             c = GetColor(Magenta);
  1497.                         break;
  1498.                 }
  1499.  
  1500.                 SetColor(c, prefLoc[index].prefID);
  1501.                 break;
  1502.             default:
  1503.                 Assert_(FALSE);;
  1504.             }
  1505.         }
  1506.         break;
  1507.     case ALIASREC:
  1508.         {
  1509.             // Read old alias pref from resource
  1510.             FSSpec folder;
  1511.             folder.vRefNum = folder.parID = refNum_Undefined;
  1512.             LString::CopyPStr(NON_EXISTENT_NAME, folder.name, 32);
  1513.             AliasHandle a = NULL;
  1514.             Boolean gotAlias = false;
  1515.             Boolean fromResource = false;
  1516.             
  1517.             // XP prefs: Read alias as binary type
  1518.             if ( sPrefFileVersion != 3 && IsNewPrefFormat(index) )
  1519.             {
  1520.                 int size;
  1521.                 void* alias;
  1522.                 if (PREF_CopyBinaryPref( prefLoc[index].prefName, &alias, &size ) == 0)
  1523.                 {
  1524.                     PtrToHand(alias, &(Handle) a, size);
  1525.                     XP_FREE(alias);
  1526.                 }
  1527.             }
  1528.             else if (UsePreferencesResFile())
  1529.             {
  1530.                 a = (AliasHandle)::Get1Resource( ALIASREC, prefLoc[index].resID );
  1531.                 fromResource = true;
  1532.             }
  1533.  
  1534.             if (a && *a) {
  1535.                 Boolean changed;
  1536.                 SInt8 flags = ::HGetState((Handle) a);
  1537.                 ::HNoPurge((Handle )a);
  1538.                 OSErr err = ::ResolveAlias( NULL, a, &folder, &changed );
  1539.                 gotAlias = (err == noErr);                
  1540.                 if (!gotAlias)
  1541.                     folder.vRefNum = folder.parID = refNum_Undefined;
  1542.                 ::HSetState((Handle) a, flags);
  1543.  
  1544.                 if (fromResource) {
  1545.                     if (gotAlias) {
  1546.                         // 3.0 format alias: convert to an xp preference
  1547.                         ::HLock((Handle) a);
  1548.                         PREF_SetBinaryPref( prefLoc[index].prefName, (void*) *a,
  1549.                             GetHandleSize((Handle) a) );
  1550.                         ::HUnlock((Handle) a);
  1551.                     }
  1552.                 }
  1553.                 else {
  1554.                     ::DisposeHandle((Handle) a);
  1555.                 }
  1556.             }
  1557.  
  1558.             SetFolderSpec(folder, prefLoc[index].prefID);
  1559.             
  1560.             // If there is no user preference value for the alias, or the alias
  1561.             // is invalid, then SetFolderSpec fills in the default location.
  1562.             // We need to reflect it into a default xp pref:
  1563.             if (!gotAlias) {
  1564.                 folder = GetFolderSpec(prefLoc[index].prefID);
  1565.                 AliasHandle    aliasH;
  1566.                 OSErr err = NewAlias(nil, &folder, &aliasH);
  1567.                 if (err == noErr) {
  1568.                     Size bytes = GetHandleSize((Handle) aliasH);
  1569.                     HLock((Handle) aliasH);
  1570.                     PREF_SetDefaultBinaryPref( prefLoc[index].prefName, *aliasH, bytes );
  1571.                     DisposeHandle((Handle) aliasH);
  1572.                 }
  1573.             }
  1574.         }
  1575.         break;
  1576.     case PRINTRECORD:
  1577.         {
  1578.             if (UsePreferencesResFile())
  1579.             {
  1580.                 Handle printHandle = ::Get1Resource( PRINTRECORD, prefLoc[index].resID);
  1581.                 if ( printHandle )
  1582.                 {
  1583.                     if ( !*printHandle )
  1584.                         ::LoadResource( printHandle );
  1585.                     if ( *printHandle && (::GetHandleSize(printHandle) >= sizeof(TPrint)))
  1586.                     {
  1587.                         ::HNoPurge( printHandle );
  1588.                         ::DetachResource( printHandle );
  1589.                         sPrintRec = (THPrint)printHandle;
  1590.                     }
  1591.                 }
  1592.             }
  1593.             if (sPrintRec == NULL)
  1594.             Try_    {
  1595.                 sPrintRec = UPrintingMgr::GetDefaultPrintRecord();
  1596.             }
  1597.             Catch_(inErr)    {
  1598.             }
  1599.             EndCatch_
  1600.         }
  1601.         break;
  1602.     default:
  1603.         Assert_(FALSE);;
  1604.     }
  1605. }
  1606.  
  1607. // Writes the resource
  1608. // Make sure that we are only saving into pref file resource fork,
  1609. void CPrefs::WritePreference(short index)
  1610. {
  1611.     ThrowIf_(!UsePreferencesResFile());
  1612.     switch(prefLoc[index].resType)    {
  1613.     case ALIASREC:
  1614.         {
  1615.             // --ML ?? this comment:
  1616.             // Do not save TemporaryFolder special case. Do not save it if
  1617.             // it points to the temp directory
  1618.         }
  1619.         break;
  1620.     case PRINTRECORD:
  1621.         {
  1622.             if (sPrintRec)
  1623.             {
  1624.                 AssertResourceExist(PRINTRECORD, prefLoc[index].resID);
  1625.                 Handle printHandle = ::Get1Resource( PRINTRECORD, prefLoc[index].resID );
  1626.                 ThrowIfNil_(printHandle);
  1627.                 ThrowIfNil_(*printHandle);
  1628.                 SInt8 flags = ::HGetState(printHandle);
  1629.                 ::HNoPurge(printHandle);
  1630.                 StHandleLocker lock((Handle)sPrintRec);
  1631.                 ThrowIfOSErr_(::PtrToXHand(*sPrintRec, printHandle, sizeof(TPrint)));
  1632.                 ::ChangedResource( printHandle );
  1633.                 ::WriteResource(printHandle);
  1634.                 ::HSetState(printHandle, flags);
  1635.             }
  1636.         }
  1637.         break;
  1638.     default:
  1639.         break;
  1640.     }
  1641. }
  1642.  
  1643. // NOTE: the caller of this method is responsible for disposing of the
  1644. // returned window data handle
  1645.  
  1646. Handle CPrefs::ReadWindowData( short resID )
  1647. {
  1648.     Handle theWindowData = NULL;
  1649.     try {
  1650.         AssertPrefsFileOpen( fsRdPerm );
  1651.         if (UsePreferencesResFile()) {        
  1652.             theWindowData = ::Get1Resource(WINDOWREC, resID);
  1653.             if (theWindowData) {
  1654.                 ::HNoPurge(theWindowData);
  1655.                 ::DetachResource(theWindowData);
  1656.                 ThrowIfResError_();
  1657.             }
  1658.         }
  1659.     }
  1660.     catch (...) {
  1661.         if (theWindowData != NULL)
  1662.             ::ReleaseResource(theWindowData);
  1663.         
  1664.         theWindowData = NULL;        
  1665.     }
  1666.  
  1667.     ClosePrefsFile();        
  1668.     return theWindowData;
  1669. }
  1670.  
  1671. void CPrefs::WriteWindowData( Handle data, short resID )
  1672. {
  1673.     try
  1674.         {
  1675.         ThrowIfOSErr_(AssertPrefsFileOpen(fsRdWrPerm));
  1676.         UsePreferencesResFile();
  1677.         AssertResourceExist( WINDOWREC, resID );
  1678.  
  1679.         Handle        resHandle = ::Get1Resource( WINDOWREC, resID );
  1680.         ThrowIfNil_( resHandle );
  1681.         ThrowIfNil_( *resHandle );
  1682.         SInt8 flags = ::HGetState(resHandle);
  1683.         ::HNoPurge(resHandle);
  1684.  
  1685.         long        size;
  1686.         size = ::GetHandleSize( data );
  1687.  
  1688.         ::SetHandleSize( resHandle, size );
  1689.         ThrowIfMemError_();
  1690.  
  1691.         ::BlockMoveData( *data, *resHandle, size );
  1692.         ::ChangedResource(resHandle);
  1693.         ::WriteResource(resHandle);
  1694.         ::HSetState(resHandle, flags);
  1695.         }
  1696.     catch (...)
  1697.         {
  1698.         
  1699.         }
  1700.  
  1701.     ClosePrefsFile();        
  1702. }
  1703.   
  1704. Boolean CPrefs::UsePreferencesResFile()
  1705. {
  1706.     if (sPrefFileResID != refNum_Undefined)
  1707.     {
  1708.         ::UseResFile(sPrefFileResID);
  1709.         return TRUE;
  1710.     }
  1711.     return FALSE;
  1712. }
  1713.  
  1714. Boolean CPrefs::UseApplicationResFile()
  1715. {
  1716.     ::UseResFile(LMGetCurApRefNum());
  1717.     return TRUE;
  1718. }
  1719.  
  1720. // Find the Preference folder -- Three cases:
  1721. //  1. User launched a specific prefs file. Its parent is the prefs folder.
  1722. //  2. Single profile found. Prefs folder is the default.
  1723. //  3. Multiple profiles. Prompt user for prefs folder.
  1724. CPrefs::PrefErr CPrefs::InitPrefsFolder(short fileType)
  1725. {
  1726.     PrefErr result = eOK;
  1727.     Boolean showProfiles = false;
  1728.     FSSpec prefsFolder, prefSpec;
  1729.     
  1730.     CUserProfile::InitUserProfiles();
  1731.     
  1732.     // A "profile" fileType means the Profile Manager was launched,
  1733.     // so always show the profile selection dialog.
  1734.     if (fileType == FILE_TYPE_PROFILES)
  1735.         showProfiles = true;
  1736.     
  1737.     // Actually for the time being we always want the Profile Manager to appear so just set
  1738.     // showProfiles to true.  Fix things when we get the external app to invoke the Profile
  1739.     // Manager back into the public source tree.
  1740.     showProfiles = true;
  1741.     
  1742.     FSSpec usersFolder;
  1743.     Boolean foundPrefs = FindDefaultPreferencesFolder(usersFolder, usersFolderName, true);
  1744.     if (!foundPrefs) {
  1745.         ErrorManager::PlainAlert(mPREFS_CANNOT_CREATE_PREFS_FOLDER);
  1746.         return eAbort;
  1747.     }
  1748.     
  1749.     CPrefs::SetFolderSpec( usersFolder, CPrefs::UsersFolder );
  1750.         
  1751.     if ( sPrefFile )
  1752.     {
  1753.         sPrefFile->GetSpecifier( prefSpec );
  1754.         ThrowIfOSErr_( CFileMgr::FolderSpecFromFolderID(
  1755.             prefSpec.vRefNum, prefSpec.parID, prefsFolder ) );
  1756.     }
  1757.     else
  1758.     
  1759.     {
  1760.         ProfileErr        err;
  1761.         
  1762.         usersFolder = CPrefs::GetFilePrototype( CPrefs::UsersFolder );
  1763.         if ( fileType != STARTUP_TYPE_NETPROFILE)
  1764.             // Ñ╩handle user profile here
  1765.             err = CUserProfile::GetUserProfile( usersFolder, prefsFolder, showProfiles, fileType );
  1766.         else
  1767.             err = CUserProfile::CreateNetProfile(usersFolder, prefsFolder);
  1768.         
  1769.         // Ñ first time through we get the "eNeedUpgrade" error
  1770.         if ( err == eNeedUpgrade )
  1771.         {
  1772.             result = eNeedUpgrade;
  1773.  
  1774.             // Ñ╩point to the old 3.0 Netscape ─ folder 
  1775.             // (but don't create it if it doesn't exist).
  1776.             if ( !FindDefaultPreferencesFolder( prefsFolder, prefFolderName, false ) )
  1777.             {
  1778.                 // Ñ no Netscape ─, so do the upgrade right now
  1779.                 // !! if returns error then need to Quit...
  1780.                 sPrefFileVersion = 0;
  1781.                 err = CUserProfile::HandleUpgrade( prefsFolder );
  1782.                 
  1783.                 if ( err == eOK )
  1784.                     result = eOK;
  1785.                 else if ( err == eRunAccountSetup )
  1786.                     result = eRunAccountSetup; // Ñ╩are we having fun yet?
  1787.                 else
  1788.                     result = eAbort;
  1789.             }
  1790.         }
  1791.         else if ( err == eRunAccountSetup )
  1792.             result = eRunAccountSetup;
  1793.         else if ( (err == eUserCancelled) || (err == eUnknownError) )
  1794.             result = eAbort;
  1795.     }
  1796.     
  1797.     CPrefs::SetFolderSpec( prefsFolder, CPrefs::MainFolder );
  1798.     return result;
  1799. }
  1800.  
  1801. /*    
  1802.     FindRequiredGutsFolder
  1803.     
  1804.     Algorithm (given definitons of usersFolder, mainFolder, netscapeFolder) 
  1805.     inLaunchWithPrefs is true if user double clicked on a preferences folder.
  1806.     
  1807.     if inLaunchWithPrefs
  1808.         try to find in the mainFolder (parent of folder user clicked on)
  1809.         try to find in the netscapeFolder (where app is)
  1810.         try to find in the usersFolder (where the user prefs directories are)
  1811.     
  1812.     if !inLaunchWithPrefs
  1813.         try to find in the app folder
  1814.         try to find in the Netscape ─ folder (ie prefs)    
  1815. */
  1816.  
  1817. Boolean CPrefs::FindRequiredGutsFolder(Boolean inLaunchWithPrefs)
  1818. {
  1819.     FSSpec    usersFolder;        // always the "Netscape Users" in the preferences folder
  1820.     FSSpec    mainFolder;                // if inLaunchWithPrefs, parent of prefs folder, otherwise "Netscape ─"
  1821.     FSSpec    netscapeFolder;            // the folder containing the app
  1822.     FSSpec    gutsFolder;
  1823.     OSErr    tempErr;
  1824.     
  1825.     ::GetIndString( gutsFolder.name, 300, prefRequiredGutsName );
  1826.  
  1827.     // really get directory IDs for these folders (not parIDs)
  1828.     netscapeFolder = GetFilePrototype(NetscapeFolder);
  1829.     usersFolder = GetFilePrototype(UsersFolder);
  1830.     mainFolder = GetFilePrototype(MainFolder);
  1831.     
  1832.     // see note below, but basically we are using parID of the gutsFolder
  1833.     // and of the parent foldres to mean the IDs of the folders
  1834.     if (inLaunchWithPrefs)
  1835.     {
  1836.         tempErr = CFileMgr::FindWFolderInFolder(mainFolder.vRefNum, mainFolder.parID, gutsFolder.name ,&gutsFolder.vRefNum, &gutsFolder.parID);
  1837.         if (noErr != tempErr)
  1838.         {
  1839.             tempErr = CFileMgr::FindWFolderInFolder(netscapeFolder.vRefNum, netscapeFolder.parID, gutsFolder.name ,&gutsFolder.vRefNum, &gutsFolder.parID);
  1840.             if (noErr != tempErr)
  1841.             {
  1842.                 tempErr = CFileMgr::FindWFolderInFolder(usersFolder.vRefNum, usersFolder.parID, gutsFolder.name ,&gutsFolder.vRefNum, &gutsFolder.parID);
  1843.             }
  1844.         }    
  1845.     }
  1846.     else
  1847.     {
  1848.         tempErr = CFileMgr::FindWFolderInFolder(netscapeFolder.vRefNum, netscapeFolder.parID, gutsFolder.name ,&gutsFolder.vRefNum, &gutsFolder.parID);
  1849.         if (noErr != tempErr)
  1850.         {
  1851.             tempErr = CFileMgr::FindWFolderInFolder(mainFolder.vRefNum, mainFolder.parID, gutsFolder.name ,&gutsFolder.vRefNum, &gutsFolder.parID);
  1852.         }
  1853.     }
  1854.     
  1855.     // return false in case of error
  1856.     if (noErr == tempErr)
  1857.     {
  1858.         FSSpec toSet;
  1859.         
  1860.         // so what we really got from FindWFolderInFolder is the directory ID
  1861.         // (a shorthand reference to a specification).  Now lets convert it
  1862.         // into a proper specification for a folder
  1863.         CFileMgr::FolderSpecFromFolderID(gutsFolder.vRefNum, gutsFolder.parID, toSet);
  1864.  
  1865.         SetFolderSpec(toSet, CPrefs::RequiredGutsFolder);
  1866.         return (true);
  1867.     }
  1868.     else
  1869.     {
  1870.         return (false);
  1871.     }
  1872. }
  1873.  
  1874.  
  1875. // All preferences designated "NOTSAVED" are initialized here
  1876. void CPrefs::InitializeUnsavedPref(short index)
  1877. {
  1878.     switch(prefLoc[index].prefID)    {
  1879.         case NetscapeFolder:
  1880.             break;        // Initialized automatically on startup
  1881.         case MainFolder:
  1882.         case UsersFolder:
  1883.         case RequiredGutsFolder:
  1884.             break;        // Moved to InitPrefsFolder
  1885.         case NewsFolder:
  1886.         case SecurityFolder:
  1887.         case SARCacheFolder:
  1888.         case NetHelpFolder:
  1889.                         FSSpec folder;
  1890.                         folder.vRefNum = folder.parID = refNum_Undefined;
  1891.                         SetFolderSpec(folder, prefLoc[index].prefID);
  1892.                         break;
  1893.         case WindowBkgnd:
  1894.             RGBColor c;
  1895.             c.red = c.green = c.blue = 0xC0C0;
  1896.             SetColor(c, prefLoc[index].prefID);
  1897.             break;
  1898.         case Black:
  1899.             c.red = c.green = c.blue = 0;
  1900.             SetColor(c, prefLoc[index].prefID);
  1901.             break;        
  1902.         case White:
  1903.             c.red = c.green = c.blue = 0xFFFF;
  1904.             SetColor(c, prefLoc[index].prefID);
  1905.             break;
  1906.         case Blue:
  1907.             c.red = c.green = 0;
  1908.             c.blue = 0xFFFF;
  1909.             SetColor(c, prefLoc[index].prefID);
  1910.             break;
  1911.         case Magenta:
  1912.             c.red = 0x5500;
  1913.             c.green = 0x1A00;
  1914.             c.blue = 0x8B00;
  1915.             SetColor(c, prefLoc[index].prefID);
  1916.             break;
  1917.         default:
  1918.              Assert_(FALSE);;    // Unsaved prefs need to be initialized statically
  1919.     }
  1920. }
  1921.  
  1922. void CPrefs::SetModified()
  1923. {
  1924.     sDirty = TRUE;
  1925. }
  1926.  
  1927. // Strings
  1928. Boolean CPrefs::SetString(const char* newString, PrefEnum id)
  1929. {
  1930.     Boolean changed = TRUE;
  1931.  
  1932.     if ( IsNewPrefFormat(id) )
  1933.     {
  1934.         changed = PREF_SetCharPref( prefLoc[id].prefName, newString );
  1935.     }
  1936.  
  1937.     PostInitializePref(id, changed);
  1938.     return changed;
  1939. }
  1940.  
  1941. // Booleans
  1942. Boolean CPrefs::SetBoolean(Boolean b, PrefEnum id)
  1943. {
  1944.     Boolean changed = FALSE;
  1945.     
  1946.     if ( IsNewPrefFormat(id) )
  1947.     {
  1948.         changed = PREF_SetBoolPref( prefLoc[id].prefName, b );
  1949.     }
  1950.     PostInitializePref(id, changed);
  1951.     return changed;
  1952. }
  1953.  
  1954. // Longs
  1955. Boolean CPrefs::SetLong(Int32 value, PrefEnum id)
  1956. {
  1957.     Boolean changed = FALSE;
  1958.     switch(id)    // Constrain the values
  1959.     {
  1960.         case Connections:
  1961.             ConstrainTo( CONNECTIONS_MIN, CONNECTIONS_MAX, value );
  1962.             break;
  1963.         case BufferSize:
  1964.             ConstrainTo( BUFFER_MIN, BUFFER_MAX, value );
  1965.             break;
  1966.         case DiskCacheSize:    
  1967.             unsigned long        maxSize;
  1968.             FSSpec                diskCacheSpec;
  1969.             diskCacheSpec = GetFolderSpec(DiskCacheFolder );
  1970.             maxSize = GetFreeSpaceInBytes( diskCacheSpec.vRefNum ) / DISK_CACHE_SCALE;
  1971.             ConstrainTo( DISK_CACHE_MIN, maxSize, value );
  1972.             break;
  1973.         case DaysTilExpire:
  1974.             if (value!= -1)
  1975.                 ConstrainTo( EXPIRE_MIN, EXPIRE_MAX, value );
  1976.             break;
  1977.         case PrintFlags:
  1978.             ConstrainTo( PRINT_CROPPED, PRINT_RESIZED, value );
  1979.             break;
  1980.         case NewsArticlesMax:
  1981.             ConstrainTo( NEWS_ARTICLES_MIN, NEWS_ARTICLES_MAX, value );
  1982.             break;
  1983.         case CheckDocuments:
  1984.             ConstrainTo( (long)CU_CHECK_PER_SESSION, (long)CU_NEVER_CHECK,value );
  1985.             break;
  1986.         case BackgroundColors:
  1987.             break;
  1988.         case MessageFontStyle:
  1989.             ConstrainTo(MSG_PlainFont, MSG_BoldItalicFont, value);
  1990.             break;
  1991.         case MessageFontSize:
  1992.             ConstrainTo(MSG_NormalSize, MSG_Smaller, value);
  1993.             break;
  1994.         case ProxyConfig:
  1995.             ConstrainTo(PROXY_STYLE_MANUAL, PROXY_STYLE_NONE, value);
  1996.             break;
  1997.         case StartupAsWhat:
  1998.             ConstrainTo(STARTUP_BROWSER, STARTUP_VISIBLE, value);
  1999.             break;
  2000.         case BiffTimeout:
  2001.             ConstrainTo(1, 1200, value);
  2002.             break;
  2003.         case AskMozPassword:
  2004.             ConstrainTo(-1, 1, value);    // See secnav.h, SECNAV_SetPasswordPrefs
  2005.             break;
  2006.         case SortMailBy:
  2007.         case SortNewsBy:
  2008.             ConstrainTo(MAIL_SORT_BY_DATE, MAIL_SORT_BY_SENDER, value);    // See secnav.h, SECNAV_SetPasswordPrefs
  2009.             break;
  2010.         default:
  2011.             break;
  2012.     }
  2013.     if ( IsNewPrefFormat(id) )
  2014.     {
  2015.         changed = PREF_SetIntPref( prefLoc[id].prefName, value );
  2016.     }
  2017.     PostInitializePref(id, changed);
  2018.     return changed;
  2019. }
  2020.  
  2021. // RGB color
  2022. Boolean CPrefs::SetColor(const RGBColor& newColor, PrefEnum id)
  2023. {
  2024.     Boolean changed = FALSE;
  2025.  
  2026.     if ( IsNewPrefFormat(id) )
  2027.     {
  2028.         changed = PREF_SetColorPref( prefLoc[id].prefName,
  2029.             newColor.red >> 8, newColor.green >> 8, newColor.blue >> 8 );
  2030.     }
  2031.     else {
  2032.         if ((sColors[id - FIRSTCOLOR].red != newColor.red) ||
  2033.             (sColors[id - FIRSTCOLOR].green != newColor.green) ||
  2034.             (sColors[id - FIRSTCOLOR].blue != newColor.blue))
  2035.             changed = TRUE;
  2036.         sColors[id - FIRSTCOLOR] = newColor;
  2037.     }
  2038.     PostInitializePref(id, changed);    
  2039.     return changed;
  2040. }
  2041.  
  2042. extern const char* CacheFilePrefix;
  2043. Boolean CPrefs::SetFolderSpec( const FSSpec& newSpec , PrefEnum id )
  2044. {
  2045.     Boolean changed;
  2046.     
  2047.     FSSpec    oldSpec = sFileIDs[id - FIRSTFOLDER]->GetFolderSpec();
  2048.     CStr63    oldName( oldSpec.name );
  2049.     CStr63    newName( newSpec.name );
  2050.     changed =     !( oldSpec.vRefNum == newSpec.vRefNum ) &&
  2051.                             ( oldSpec.parID == newSpec.parID ) &&
  2052.                             ( newName == oldName );
  2053.     if (changed)
  2054.     if ((id == DiskCacheFolder) && !sReading)
  2055.     {
  2056.         NET_SetDiskCacheSize( 0 );    // A hack to clean up the old cache directory
  2057.         NET_CleanupCacheDirectory( "", CacheFilePrefix );
  2058.         NET_SetDiskCacheSize( CPrefs::DiskCacheSize );
  2059.     }
  2060.     sFileIDs[id - FIRSTFOLDER]->SetFolderSpec(newSpec, id);
  2061.     PostInitializePref(id, changed);
  2062.     
  2063.     return changed;
  2064. }
  2065.  
  2066. // Called from mdmac.c to find the Java component folder
  2067. OSErr FindGutsFolder(FSSpec* outSpec)
  2068. {
  2069.     *outSpec = CPrefs::GetFolderSpec(CPrefs::RequiredGutsFolder);
  2070.  
  2071.     return noErr;
  2072. }
  2073.  
  2074. // Called from mdmac.c to find the Java component folder
  2075. OSErr FindNetscapeFolder(FSSpec* outSpec)
  2076. {
  2077.     *outSpec = CPrefs::GetFolderSpec(CPrefs::NetscapeFolder);
  2078.  
  2079.     return noErr;
  2080. }
  2081.  
  2082. // Called from mdmac.c to find the Java component folder
  2083. OSErr FindJavaDownloadsFolder(FSSpec* outSpec)
  2084. {
  2085.     *outSpec = CPrefs::GetFilePrototype(CPrefs::NetscapeFolder);
  2086.     CStr255 downName;
  2087.     ::GetIndString( downName, 14000, 5 );
  2088. #ifdef DEBUG
  2089.     if (downName.Length() < 4 )
  2090.         XP_ASSERT(false);    // Someone blew away our string
  2091. #endif
  2092.     LString::CopyPStr( downName, outSpec->name, 32 );
  2093.     return noErr;
  2094. }
  2095.  
  2096. // Called from mkhelp.c to get the standard location of the NetHelp folder as a URL
  2097. char * FE_GetNetHelpDir()
  2098. {
  2099.     FSSpec        nethelpFolder = CPrefs::GetFolderSpec(CPrefs::NetHelpFolder);
  2100.     
  2101.     return CFileMgr::GetURLFromFileSpec(nethelpFolder);
  2102. }
  2103.  
  2104. Boolean CPrefs::GetBoolean(PrefEnum id)
  2105. {
  2106.     if ( IsNewPrefFormat(id) ) {
  2107.         XP_Bool value;
  2108.         PREF_GetBoolPref( prefLoc[id].prefName, &value );
  2109.         return value;
  2110.     }
  2111.     else return false;
  2112. }
  2113.  
  2114. Int32    CPrefs::GetLong(PrefEnum id)
  2115. {
  2116.     if ( IsNewPrefFormat(id) ) {
  2117.         int32 value;
  2118.         PREF_GetIntPref( prefLoc[id].prefName, &value );
  2119.         return (Int32) value;
  2120.     }
  2121.     else return 0;
  2122. }
  2123.  
  2124. char *    CPrefs::GetStaticString()
  2125. {
  2126.     static char        cStrings[kStaticStrCount][kStaticStrLen];
  2127.     static short    currentCString = 0;
  2128.  
  2129.     currentCString = (currentCString + 1) % kStaticStrCount;
  2130.     char* strbuffer = cStrings[currentCString];
  2131.  
  2132.     return (strbuffer);
  2133. }
  2134.         
  2135. CStr255    CPrefs::GetString(PrefEnum id)
  2136. {
  2137.     // --xp prefs Note:
  2138.     // Be aware of performance impact here.  For some frequently
  2139.     // accessed prefs, we might want to cache value locally
  2140.     // (e.g. HomePage is queried every time menu/toolbar is updated).
  2141.     if ( IsNewPrefFormat(id) ) {
  2142.         int len = kStaticStrLen;
  2143.         char * value = GetStaticString();
  2144.         
  2145.         // special case to handle "one-time homepage".  If a homepage
  2146.         // override is requested and the user hasn't seen it yet,
  2147.         // load the override page instead.
  2148.         if (id == HomePage) {
  2149.             XP_Bool override = false;
  2150.             PREF_GetBoolPref("browser.startup.homepage_override", &override);
  2151.             if (override) {
  2152.                 char* url = NULL;
  2153.                 PREF_CopyConfigString("startup.homepage_override_url", &url);
  2154.                 PREF_SetBoolPref("browser.startup.homepage_override", false);
  2155.                 if (url && *url) {
  2156.                     strncpy(value, url, len);
  2157.                     XP_FREE(url);
  2158.                     return value;
  2159.                 }
  2160.             }        
  2161.         }
  2162.         
  2163.         PREF_GetCharPref( prefLoc[id].prefName, value, &len );
  2164.         return value;
  2165.     }
  2166.     else return CStr255::sEmptyString;
  2167. }
  2168.         
  2169. char* CPrefs::GetCharPtr( PrefEnum id )
  2170. {
  2171.     if ( IsNewPrefFormat(id) )
  2172.     {
  2173.         char* strbuffer = GetStaticString();
  2174.         int len = kStaticStrLen;
  2175.         PREF_GetCharPref( prefLoc[id].prefName, strbuffer, &len );
  2176.         return strbuffer;
  2177.     }
  2178.     else return CStr255::sEmptyString;
  2179. }
  2180.  
  2181. // --ML no longer inline
  2182. const RGBColor& CPrefs::GetColor( PrefEnum id )
  2183. {
  2184.     if ( IsNewPrefFormat(id) )
  2185.     {
  2186.         uint8 r, g, b;
  2187.         PREF_GetColorPref( prefLoc[id].prefName, &r, &g, &b );
  2188.         static RGBColor color;
  2189.         color.red = r << 8;
  2190.         color.green = g << 8;
  2191.         color.blue = b << 8;
  2192.         return color;
  2193.     }
  2194.  
  2195.     return sColors[ id - FIRSTCOLOR ];
  2196. }
  2197.  
  2198. FSSpec    CPrefs::GetFolderSpec( PrefEnum id )
  2199. {
  2200.     Assert_(sFileIDs[id - FIRSTFILESPEC]);
  2201.     if (sFileIDs[id - FIRSTFILESPEC] == NULL)
  2202.     {
  2203.         FSSpec dummy;
  2204.         dummy.vRefNum = dummy.parID = 0;
  2205.         return dummy;
  2206.     }
  2207.     else
  2208.         return sFileIDs[id - FIRSTFILESPEC]->GetFolderSpec(); 
  2209. }
  2210.  
  2211. FSSpec CPrefs::GetFilePrototype(PrefEnum id)
  2212. {
  2213. //    Assert_((id >= FIRSTFILESPEC) && (id <= LastFolder));
  2214.     Assert_(sFileIDs[id - FIRSTFILESPEC]);
  2215.     if (sFileIDs[id - FIRSTFILESPEC] == NULL)
  2216.     {    
  2217.         FSSpec dummy;
  2218.         dummy.vRefNum = dummy.parID = 0;
  2219.         return dummy;
  2220.     }
  2221.     else
  2222.         return sFileIDs[id - FIRSTFILESPEC]->GetFilePrototype(); 
  2223. }
  2224.  
  2225. char * CPrefs::GetCachePath()
  2226. {
  2227.     if (sCachePath == NULL)
  2228.     {
  2229.         FSSpec cacheFolder = GetFilePrototype( DiskCacheFolder );
  2230.         sCachePath = CFileMgr::PathNameFromFSSpec(cacheFolder, FALSE);
  2231.     }
  2232.     return sCachePath;
  2233. }
  2234.  
  2235. THPrint    CPrefs::GetPrintRecord()
  2236. {
  2237.  
  2238.     /*        If we have already loaded a print record, whatever its origin, use that.
  2239.         If not, create the default one.  Note that the standard "get our print record"
  2240.         code already loads the default one, if necessary.  Checking again right here
  2241.         is useful only for dynamically detecting when a printer has recently been
  2242.         chosen on a machine for which no printer has ever before been chosen.
  2243.         (It was a bug; don't hunt me down for this one.)
  2244.     */
  2245.  
  2246.     if (!sPrintRec)
  2247.         try {
  2248.             sPrintRec = UPrintingMgr::GetDefaultPrintRecord();
  2249.         } catch(...) {
  2250.         }
  2251.     return sPrintRec;
  2252. }
  2253.  
  2254. // --Admin Kit support. Animation file must live in Essential Files
  2255. // or the user's profile folder.
  2256. void CPrefs::OpenAnimationFile(FSSpec& preferredAnim, FSSpec& secondaryAnim)
  2257. {
  2258.     char* animFileName;
  2259.     if ( PREF_CopyConfigString("mac_animation_file", &animFileName) == PREF_NOERROR )
  2260.     {
  2261.         Try_ {
  2262.             LFile* animFile = nil;
  2263.             LString::CopyPStr( (CStr32) animFileName, preferredAnim.name, 32 );
  2264.             if (CFileMgr::FileExists(preferredAnim)) {
  2265.                 animFile = new LFile(preferredAnim);
  2266.             } else {
  2267.                 LString::CopyPStr( (CStr32) animFileName, secondaryAnim.name, 32 );
  2268.                 if (CFileMgr::FileExists(secondaryAnim)) {
  2269.                     animFile = new LFile(secondaryAnim);
  2270.                 }
  2271.             }
  2272.             XP_FREE(animFileName);
  2273.             if (animFile) {
  2274.                 animFile->OpenResourceFork(fsRdPerm);
  2275.                 CSpinningN::AnimResFile() = animFile->GetResourceForkRefNum();
  2276.                 
  2277.                 MoveResourceMapBelowApp();
  2278.             }
  2279.         }
  2280.         Catch_(inErr)
  2281.         {    // file not found or something. Just ignore it.
  2282.         }
  2283.     }
  2284. }
  2285.  
  2286. Boolean CPrefs::HasCoBrand()
  2287. {
  2288.     // Show co-brand if using a custom animation file
  2289.     // (No longer true: or logo URL is changed.)
  2290.     return ( CSpinningN::AnimResFile() != refNum_Undefined );
  2291.       /* || ( PREF_CopyConfigString("toolbar.logo.url", nil) == PREF_NOERROR );*/
  2292. }
  2293.  
  2294. Boolean CPrefs::IsLocked(PrefEnum id)
  2295. {
  2296.     if ( IsNewPrefFormat(id) ) {
  2297.         return (Boolean) PREF_PrefIsLocked( prefLoc[id].prefName );
  2298.     }
  2299.     else {
  2300.         return false;
  2301.     }
  2302. }
  2303.  
  2304. char* CPrefs::Concat(const char* base, const char* suffix)
  2305. {
  2306.     const size_t kBufLength = 256;
  2307.     static char buf[kBufLength];
  2308.     size_t blen = strlen(base);
  2309.     size_t slen = strlen(suffix);
  2310.     Assert_(blen+slen < kBufLength);
  2311.     memcpy(buf, base, blen);
  2312.     memcpy(&buf[blen], suffix, slen);
  2313.     buf[blen + slen] = '\0';
  2314.     return buf;
  2315. }
  2316.  
  2317. void CPrefs::PostInitializePref(PrefEnum id, Boolean changed)
  2318. {
  2319.     if (changed && !sReading)
  2320.     {
  2321.         sDirty = TRUE;
  2322.         if (gPrefBroadcaster != NULL)
  2323.             gPrefBroadcaster->BroadcastMessage(msg_PrefsChanged, &id);    
  2324.     }
  2325.     
  2326.     switch(id)    {
  2327. // Booleans
  2328.         case ThreadMail:
  2329.         case ThreadNews:
  2330.         case ShowToolbar:
  2331.         case DelayImages:
  2332.         case ShowStatus:
  2333.         case ShowURL:
  2334.         case DisplayWhileLoading:
  2335.             break;
  2336.         case MailUseFixedWidthFont:
  2337.             break;
  2338.         case LeaveMailOnServer:
  2339.             break;
  2340.     
  2341.         case MailCCSelf:
  2342.             break;
  2343.     
  2344.         case NewsCCSelf:
  2345.             break;
  2346.         case UseFancyNews:
  2347.         case ShowAllNews:    
  2348.             break;            
  2349.         case AnchorUnderline:
  2350.         case UseFancyFTP:
  2351.         case LoadHomePage:
  2352.         case ExpireNever:
  2353.         case CustomLinkColors:
  2354.         case ShowDirectory:
  2355.         case AgreedToLicense:
  2356.         case EnteringSecure:    
  2357.         case LeavingSecure:
  2358.         case ViewingMixed:
  2359.         case SubmittingInsecure:
  2360.         case ShowSecurity:
  2361.         case CustomVisitedColors:
  2362.         case CustomTextColors:
  2363.  
  2364.         case DefaultMailDelivery:
  2365.         case EnableActiveScrolling:
  2366. #ifdef EDITOR
  2367.         case EditorUseCustomColors:
  2368.         case EditorUseBackgroundImage:
  2369.         case PublishMaintainLinks:
  2370.         case PublishKeepImages:
  2371.         case ShowCopyright:
  2372.         case ShowFileEditToolbar:
  2373.         case ShowCharacterToolbar:
  2374.         case ShowParagraphToolbar:
  2375. #endif
  2376.             break;
  2377.             
  2378.         case UseDocumentColors:
  2379.             break;
  2380.         case UseSigFile:
  2381.             break;
  2382.         case AutoDetectEncoding:
  2383.         case StrictlyMIME:
  2384. #ifdef MOZ_MAIL_NEWS
  2385.             MIME_ConformToStandard(GetBoolean(id));
  2386. #endif // MOZ_MAIL_NEWS
  2387.             break;
  2388.         case UseUtilityBackground:
  2389.             break;
  2390.         case UseInlineViewSource:
  2391.             break;
  2392.             
  2393.         case ShowToolTips:
  2394.             CToolTipAttachment::Enable(GetBoolean(ShowToolTips));
  2395.             break;
  2396.             
  2397.         case UseInternetConfig:    
  2398.             break;
  2399.  
  2400.         case EnableJava:
  2401. #if defined (JAVA)
  2402.             LJ_SetJavaEnabled( (PRBool)CPrefs::GetBoolean( CPrefs::EnableJava ) );
  2403. #endif /* defined (JAVA) */
  2404.             break;
  2405. // Longs
  2406.         case LicenseVersion:    
  2407.         case TopLeftHeader:
  2408.         case TopMidHeader:
  2409.         case TopRightHeader:
  2410.         case BottomLeftFooter:
  2411.         case BottomMidFooter:
  2412.         case BottomRightFooter:
  2413.         case PrintBackground:
  2414.         case StartupAsWhat:
  2415.         case StartupBitfield:
  2416.         case SortMailBy:
  2417.         case SortNewsBy:
  2418.         case NewsPaneConfig:
  2419.         case MailPaneConfig:
  2420.         case Ciphers:
  2421.         case MailHeaderDisplay:
  2422.         case NewsHeaderDisplay:
  2423.         case AutoSaveTimeDelay:
  2424.         // NOPs
  2425.             break;
  2426.         case DaysTilExpire:
  2427.             if (GetLong(id) != -1)
  2428.                 GH_SetGlobalHistoryTimeout( SECONDS_PER_DAY * GetLong(id) );
  2429.             else
  2430.                 GH_SetGlobalHistoryTimeout( -1 );
  2431.             break;
  2432.         case Connections:
  2433.             NET_ChangeMaxNumberOfConnectionsPerContext(GetLong(id));
  2434.             break;
  2435.         case BufferSize:
  2436.             NET_ChangeSocketBufferSize( GetLong(id) );
  2437.             break;
  2438.         case PrintFlags:
  2439.         case NewsArticlesMax:
  2440.             NET_SetNumberOfNewsArticlesInListing(GetLong(id));
  2441.             break;
  2442.         case CheckDocuments:
  2443.             NET_SetCacheUseMethod( (CacheUseEnum)GetLong(id) );
  2444.             break;
  2445.         case FileSortMethod:
  2446.         case ToolbarStyle:
  2447.         case DefaultCharSetID:
  2448.         case DefaultFontEncoding:
  2449.             break;
  2450.         case BackgroundColors:
  2451.             LO_Color loColor;
  2452.             loColor = MakeLOColor(GetColor(TextBkgnd ));
  2453.             LO_SetDefaultColor( LO_COLOR_BG, loColor.red, loColor.green, loColor.blue);
  2454.             break;
  2455.         case MessageFontStyle:
  2456.         case MessageFontSize:
  2457.             break;
  2458. // Strings
  2459.         case AcceptLanguage:
  2460.             break;
  2461.         case HomePage:
  2462.             break;
  2463.         case NewsHost:
  2464.             NET_SetNewsHost( GetCharPtr(id) );
  2465.             break;
  2466.         case UserName:
  2467.             break;
  2468.         case UserEmail:
  2469.             break;
  2470.         case SMTPHost:
  2471. #if defined(MOZ_MAIL_COMPOSE) || defined(MOZ_MAIL_NEWS)
  2472.             NET_SetMailRelayHost( GetCharPtr(id));
  2473. #endif // MOZ_MAIL_COMPOSE || MOZ_MAIL_NEWS
  2474.             break;
  2475.         case SOCKSHost:
  2476.         case SOCKSPort:
  2477.             CStr31 numstr;
  2478.             ::NumToString(GetLong(SOCKSPort), numstr);
  2479.             NET_SetSocksHost(BuildProxyString(GetString(SOCKSHost), numstr));
  2480.             break;
  2481.         case Organization:
  2482.             // Should we reset mail window here too?
  2483.             break;
  2484.         case PopHost:
  2485. //            MSG_SetPopHost( GetCharPtr(id) );
  2486.             if ( GetBoolean( RememberMailPassword ) )
  2487.                 NET_SetPopPassword( GetCharPtr( MailPassword) );
  2488.             else
  2489.                 NET_SetPopPassword(NULL);
  2490.             break;
  2491.             
  2492.         case DefaultMailCC:
  2493.             break;
  2494.         case DefaultNewsCC:
  2495.             break;
  2496.         case ReplyTo:
  2497.             break;
  2498.         case PopID:
  2499.             NET_SetPopUsername(GetCharPtr(PopID));
  2500.             break;
  2501.  
  2502.         case AcceptCookies:
  2503.             break;
  2504.         case UseEmailAsPassword:
  2505.             NET_SendEmailAddressAsFTPPassword( CPrefs::GetBoolean( CPrefs::UseEmailAsPassword ) );
  2506.             break;
  2507.         case SubmitFormsByEmail:
  2508.             NET_WarnOnMailtoPost( CPrefs::GetBoolean( CPrefs::SubmitFormsByEmail ) ? PR_TRUE : PR_FALSE );
  2509.             break;
  2510.         case DefaultPersonalCertificate:
  2511.             break;
  2512. // Folders
  2513.         case DownloadFolder:
  2514.         case NetscapeFolder:
  2515.         case MainFolder:
  2516.         case SignatureFile:
  2517.         case HTMLEditor:
  2518.         case ImageEditor:
  2519.             break;
  2520.         case DiskCacheFolder:
  2521.             if (sCachePath)
  2522.                 free(sCachePath);        
  2523.             sCachePath = NULL;
  2524.             break;
  2525.         case GIFBackdropFile:
  2526.             break;                
  2527.         case MailFolder:
  2528.             break;
  2529.         case NewsFolder:
  2530.             break;
  2531.         case SecurityFolder:
  2532.             break;
  2533. // Colors
  2534.         case TextFore:
  2535.             loColor = MakeLOColor(GetColor(TextFore ));
  2536.             LO_SetDefaultColor( LO_COLOR_FG , loColor.red, loColor.green, loColor.blue);
  2537.             break;
  2538.         case TextBkgnd:
  2539.             loColor = MakeLOColor(GetColor(TextBkgnd ));
  2540.             LO_SetDefaultColor( LO_COLOR_BG, loColor.red, loColor.green, loColor.blue);
  2541.             break;
  2542.         case Anchor:
  2543.             loColor = MakeLOColor(GetColor(Anchor ));
  2544.             LO_SetDefaultColor( LO_COLOR_LINK, loColor.red, loColor.green, loColor.blue);
  2545.             break;
  2546.         case Visited:
  2547.             loColor = MakeLOColor(GetColor(Visited ));
  2548.             LO_SetDefaultColor( LO_COLOR_VLINK, loColor.red, loColor.green, loColor.blue);
  2549.             break;
  2550.         case WindowBkgnd:
  2551.         case EditorText:
  2552.         case EditorLink:
  2553.         case EditorActiveLink:
  2554.         case EditorFollowedLink:
  2555.         case EditorBackground:
  2556.             break;
  2557. // Print record
  2558.         case PrintRecord:
  2559.             break;
  2560. // Misc. Together, because settings from different categories need to be combined
  2561.         case UseMailFCC:
  2562.         case MailCCFile:
  2563.             break;
  2564.         case UseNewsFCC:
  2565.         case NewsCCFile:
  2566.             break;
  2567.             
  2568.         case LimitMessageSize:
  2569.         case MaxMessageSize:
  2570.             break;
  2571.         case UseMozPassword:
  2572.         case AskMozPassword:
  2573.         case AskMozPassFrequency:
  2574.             break;
  2575. #ifdef FORTEZZA
  2576.         case FortezzaTimeoutOn:
  2577.         case FortezzaTimeout:
  2578.             if (!GetBoolean(FortezzaTimeoutOn))
  2579.                 FortezzaSetTimeout(0);
  2580.             else {
  2581.                 int timeout = GetLong(FortezzaTimeout);
  2582.  
  2583.                 if (timeout <= 0) timeout = 1;
  2584.                 FortezzaSetTimeout(timeout);
  2585.             }
  2586.             break;
  2587. #endif
  2588.             
  2589.             
  2590.         case BiffOn:
  2591.         case BiffTimeout:
  2592.         case AutoQuoteOnReply:
  2593.             break;    
  2594.         case MailPassword:
  2595.             NET_SetPopPassword( GetCharPtr( MailPassword) );
  2596.             break;
  2597.         case RememberMailPassword:
  2598.         // This depends on the loading order
  2599.         // Should be solved by the accumulator
  2600.             if ( GetBoolean( RememberMailPassword ) )
  2601.                 NET_SetPopPassword( GetCharPtr( MailPassword) );
  2602.             else
  2603.                 NET_SetPopPassword(NULL);
  2604.             break;
  2605.         default:
  2606. //            Assert_(FALSE);
  2607.             break;
  2608.     }
  2609. }
  2610.  
  2611.  
  2612. void CPrefs::Read1MimeTypes()
  2613. {
  2614.     // If the Prefs file is 3.0-format read it first
  2615.     CMimeMapper*    newMap;
  2616.     if ( sPrefFileVersion == 3 && sReading && UsePreferencesResFile() )
  2617.     {
  2618.         #define DYNAMIC_MIME_RES_TYPE     'MIME'
  2619.         #define STATIC_MIME_RES_TYPE      'SMIM'
  2620.         short howMany = ::Count1Resources( DYNAMIC_MIME_RES_TYPE );
  2621.         
  2622.         // Ñ handle the case of "first launch" so that we can read all
  2623.         //        of the MIME types out of the application's resource fork
  2624.         //        (and then write them out to prefs when we quit, so that
  2625.         //        next time we launch, they'll be in prefs)
  2626.         short i;
  2627.         Handle res;
  2628.         for ( i = 0; i < howMany; i++ )
  2629.         {
  2630.             res = ::Get1Resource( DYNAMIC_MIME_RES_TYPE, MIME_PREFS_FIRST_RESID + i );
  2631.             if ( res && *res ) {
  2632.                 newMap = CMimeMapper::CreateMapperForRes(res);
  2633.                 sMimeTypes.InsertItemsAt( 1, LArray::index_Last, &newMap );
  2634.             }
  2635.         }
  2636.         howMany = ::Count1Resources( STATIC_MIME_RES_TYPE );
  2637.         for ( i = 0; i < howMany; i++ )
  2638.         {
  2639.             res = ::GetResource( STATIC_MIME_RES_TYPE, i + 1 );
  2640.             if ( res && *res ) {
  2641.                 newMap = CMimeMapper::CreateMapperForRes(res);
  2642.                 sMimeTypes.InsertItemsAt( 1, LArray::index_Last, &newMap );
  2643.             }
  2644.         }
  2645.     }
  2646.     
  2647.     // Always read xp mime default & user prefs
  2648.     char* children;    
  2649.     if ( PREF_CreateChildList("mime", &children) == 0 )
  2650.     {    
  2651.         int index = 0;
  2652.         while (char* child = PREF_NextChild(children, &index)) {
  2653.             newMap = CMimeMapper::CreateMapperFor(child, sPrefFileVersion == 4);
  2654.             if (newMap)
  2655.                 sMimeTypes.InsertItemsAt( 1, LArray::index_Last, &newMap );
  2656.         }
  2657.         XP_FREE(children);
  2658.     }
  2659. }
  2660.  
  2661. // Try reading in from the preferences file
  2662. // If it does not work, use the app file
  2663. void CPrefs::ReadMimeTypes()
  2664. {
  2665.     Try_
  2666.     {
  2667.         Read1MimeTypes();
  2668.     }
  2669.     Catch_(inErr)
  2670.     {
  2671.     }
  2672.     EndCatch_
  2673. }
  2674.  
  2675. // Creates a mapper for an unknown type, and adds it to the list. Returns NULL on failure
  2676. CMimeMapper* CPrefs::CreateDefaultUnknownMapper(const CStr255& mimeType, Boolean doInsert)
  2677. {
  2678.     CStr255 appName;
  2679.     ::GetIndString( appName, 300, unknownAppName );
  2680.     CMimeMapper * newMapper = new CMimeMapper(CMimeMapper::Unknown, 
  2681.                             mimeType,
  2682.                             appName,
  2683.                             CStr255::sEmptyString,
  2684.                             '????',
  2685.                             'TEXT');
  2686.     if (newMapper != NULL && doInsert)
  2687.     {
  2688.         sMimeTypes.InsertItemsAt( 1, LArray::index_Last, &newMapper);
  2689.         sDirty = TRUE;
  2690.         newMapper->WriteMimePrefs();
  2691.     }
  2692.  
  2693.     return newMapper;
  2694. }
  2695.  
  2696. // Like CreateDefaultUnknownMapper, except that it uses the application SIG
  2697. CMimeMapper* CPrefs::CreateDefaultAppMapper(FSSpec &fileSpec,const char * mimeType, Boolean doInsert)
  2698. {
  2699.     FInfo finderInfo;
  2700.     OSErr err = FSpGetFInfo(&fileSpec, &finderInfo );    
  2701.     CMimeMapper * newMapper = new CMimeMapper(CMimeMapper::Launch, 
  2702.                                             CStr255(mimeType),
  2703.                                             CStr255(fileSpec.name),
  2704.                                             CStr255::sEmptyString,
  2705.                                             finderInfo.fdCreator,    // Signature
  2706.                                             'TEXT'); // File type
  2707.     if (newMapper != NULL && doInsert)
  2708.     {
  2709.         sMimeTypes.InsertItemsAt( 1, LArray::index_Last, &newMapper);
  2710.         sDirty = TRUE;
  2711.         newMapper->WriteMimePrefs();
  2712.     }
  2713.     return newMapper;
  2714. }
  2715.  
  2716. void CPrefs::SubscribeToPrefChanges( LListener *listener )
  2717. {
  2718.     if (gPrefBroadcaster == NULL)
  2719.         gPrefBroadcaster = new LBroadcaster;
  2720.         
  2721.     if (gPrefBroadcaster != NULL)
  2722.         gPrefBroadcaster->AddListener(listener);
  2723. }
  2724.  
  2725.  
  2726. void            
  2727. CPrefs::UnsubscribeToPrefChanges( LListener *listener )
  2728. {
  2729.     if (gPrefBroadcaster != NULL)
  2730.         gPrefBroadcaster->RemoveListener(listener);
  2731. }
  2732.  
  2733. void FE_RememberPopPassword(MWContext * /* context */, const char * password)
  2734. {
  2735.     CPrefs::SetString( password, CPrefs::MailPassword );
  2736. }
  2737.