/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * The contents of this file are subject to the Netscape Public License * Version 1.0 (the "NPL"); you may not use this file except in * compliance with the NPL. You may obtain a copy of the NPL at * http://www.mozilla.org/NPL/ * * Software distributed under the NPL is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL * for the specific language governing rights and limitations under the * NPL. * * The Initial Developer of this code under the NPL is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998 Netscape Communications Corporation. All Rights * Reserved. */ #include "uprefd.h" // macfe #include "ufilemgr.h" // CFileMgr #include "macutil.h" // CStringListRsrc #include "resgui.h" // res_Strings1, res_Strings2, res_StringsBoolean #include "mregistr.h" // CNotifierRegistry #include "uerrmgr.h" // ErrorManager #include "uapp.h" // FILE_TYPE_PROFILES, STARTUP_TYPE_NETPROFILE #include "macfeprefs.h" // prototypes for FindGutsFolder, FindNetscapeFolder, FindJavaDownloadsFolder #include "CToolTipAttachment.h" #include "InternetConfig.h" // CInternetConfigInterface #include "CSpinningN.h" #include "profile.h" // kProfileStrings #include // Netscape #include "glhist.h" // GH_SetGlobalHistoryTimeout #include "net.h" // PROXY_STYLE_AUTOMATIC #include "ntypes.h" #include "shistele.h" #include "proto.h" #ifndef _XP_H_ //#include "xp_mcom.h" #endif #include "msgcom.h" // MSG_NormalSize, MSG_PlainFont #include "mime.h" // MIME_ConformToStandard #include "fe_proto.h" // prototype for FE_GetNetHelpDir #include "java.h" // LJ_SetJavaEnabled #include "prefapi.h" // ns/modules/libpref /********************************************************************************* * DOGBERT XP PREFERENCES / MULTI-USER PROFILES * * New preference file format: XP text file parsed by JavaScript via libpref * (includes all user strings, bools, ints, and colors). * Some prefs (see below) are still written in old resource format. * Both old and new prefs are read & written to the existing Netscape Prefs file. * * Primary changes to this file: * - added GetUserProfile() and InitPrefsFolder() to prompt user for desired * profile (if necessary) and use that to point to base Preferences folder. * - changed order of PrefEnum entries and added XP prefName strings. * - ReadPreference, if it detects new format, only needs to call * PostProcessPrefChange for each pref to propagate the new value. * Calls to back-end will GO AWAY as modules fetch their own pref values. * - ReadPreference otherwise reads old-format file. * - WritePreference always writes new format. * - CPrefs Get/Setters use libpref calls. * - removed CPrefs storage of strings, bools, ints, and colors. * - file/folder aliases accessed as libpref binary types but still stored * in CPrefs via sFileIDs. * * Some prefs are not yet supported in XP format. * - font encodings * - window/pane positions * - protocol handlers, etc. * We at least should support the first in XP format for use by Admin Kit. *********************************************************************************/ const Int16 refNum_Undefined = -1; // Really defined in LFile.cp static LBroadcaster * gPrefBroadcaster = NULL; //=============================================================================== // Resource definitions // definitions of type and resource location of all preferences //=============================================================================== #define NOTSAVED 'NONE' #define STRINGLIST 'STR#' #define ALIASREC 'ALIS' #define PRINTRECORD 'PrRc' #define REVISION 'PRev' #define WINDOWREC 'WPSt' // Starts off with a rect, followed by variable data for each window #define REVISION_RES_ID 10000 // Resource IDs of all resources used in prefs // are defined in resgui.h enum PrefType { eStringType, eBooleanType, eFileSpecType, eLongType, eColorType, ePrintRecordType, eNoType }; struct PrefLoc { CPrefs::PrefEnum prefID; // What's my id OSType resType; // What kind of resource are we reading PrefType prefType; // How should we store this pref natively short resID; // Resource ID short refCon; // For STRINGLIST this is the index into the resource // For ALIASREC, 1 to pop up alert when not found, 0 no alert char* prefName; // XP pref name }; // This array defines what kind of preference each PrefEnum is, // and where it is stored. static PrefLoc prefLoc[] = { // Folders -- need to be before anything else, because we do not have the accumulator { CPrefs::DownloadFolder, ALIASREC, eFileSpecType, 129, 1, "browser.download_directory"}, { CPrefs::NetscapeFolder, NOTSAVED, eFileSpecType, 0, 1}, { CPrefs::MainFolder, NOTSAVED, eFileSpecType, 0, 1}, { CPrefs::UsersFolder, NOTSAVED, eFileSpecType, 0, 1}, { CPrefs::DiskCacheFolder, ALIASREC, eFileSpecType, 133, 1, "browser.cache.directory"}, { CPrefs::SignatureFile, ALIASREC, eFileSpecType, 134, 1, "mail.signature_file"}, { CPrefs::GIFBackdropFile, ALIASREC, eFileSpecType, 135, 1 }, { CPrefs::MailFolder, ALIASREC, eFileSpecType, 136, 1, "mail.directory"}, { CPrefs::NewsFolder, NOTSAVED, eFileSpecType, 0, 1 }, { CPrefs::SecurityFolder, NOTSAVED, eFileSpecType, 0, 1 }, { CPrefs::MailCCFile, ALIASREC, eFileSpecType, 137, 1, "mail.default_fcc"}, { CPrefs::NewsCCFile, ALIASREC, eFileSpecType, 138, 1, "news.default_fcc"}, { CPrefs::HTMLEditor, ALIASREC, eFileSpecType, 139, 1, "editor.html_editor"}, { CPrefs::ImageEditor, ALIASREC, eFileSpecType, 140, 1, "editor.image_editor"}, { CPrefs::RequiredGutsFolder, NOTSAVED, eFileSpecType, 0, 1}, // TJ & ROB { CPrefs::SARCacheFolder, NOTSAVED, eFileSpecType, 0, 0}, // EA { CPrefs::NetHelpFolder, NOTSAVED, eFileSpecType, 0, 0}, // Strings { CPrefs::HomePage, STRINGLIST, eStringType, res_Strings1, 1, "browser.startup.homepage" }, { CPrefs::NewsHost, STRINGLIST, eStringType, res_Strings1, 2, "network.hosts.nntp_server" }, { CPrefs::FTPProxy, STRINGLIST, eStringType, res_Strings1, 3, "network.proxy.ftp" }, { CPrefs::GopherProxy, STRINGLIST, eStringType, res_Strings1, 4, "network.proxy.gopher" }, { CPrefs::HTTPProxy, STRINGLIST, eStringType, res_Strings1, 5, "network.proxy.http" }, { /*unused*/CPrefs::NewsProxy, STRINGLIST, eStringType, res_Strings1, 6 }, { CPrefs::WAISProxy, STRINGLIST, eStringType, res_Strings1, 7, "network.proxy.wais" }, { CPrefs::FTPProxyPort, STRINGLIST, eStringType, res_Strings1, 8, "network.proxy.ftp_port" }, { CPrefs::GopherProxyPort, STRINGLIST, eStringType, res_Strings1, 9, "network.proxy.gopher_port" }, { CPrefs::HTTPProxyPort, STRINGLIST, eStringType, res_Strings1, 10, "network.proxy.http_port" }, { /*unused*/CPrefs::NewsProxyPort, STRINGLIST, eStringType, res_Strings1, 11 }, { CPrefs::WAISProxyPort, STRINGLIST, eStringType, res_Strings1, 12, "network.proxy.wais_port" }, { CPrefs::NoProxies, STRINGLIST, eStringType, res_Strings1, 13, "network.proxy.no_proxies_on" }, { CPrefs::UserName, STRINGLIST, eStringType, res_Strings1, 14, "mail.identity.username" }, { CPrefs::UserEmail, STRINGLIST, eStringType, res_Strings1, 15, "mail.identity.useremail" }, { CPrefs::SMTPHost, STRINGLIST, eStringType, res_Strings1, 16, "network.hosts.smtp_server" }, { CPrefs::SOCKSHost, STRINGLIST, eStringType, res_Strings2, 1, "network.hosts.socks_server" }, { CPrefs::SOCKSPort, STRINGLIST, eStringType, res_Strings2, 2, "network.hosts.socks_serverport" }, { CPrefs::Organization, STRINGLIST, eStringType, res_Strings2, 3, "mail.identity.organization" }, { CPrefs::SSLProxy, STRINGLIST, eStringType, res_Strings2, 4, "network.proxy.ssl" }, { CPrefs::SSLProxyPort, STRINGLIST, eStringType, res_Strings2, 5, "network.proxy.ssl_port" }, { CPrefs::PopHost, STRINGLIST, eStringType, res_Strings2, 6, "network.hosts.pop_server" }, { CPrefs::AcceptLanguage, STRINGLIST, eStringType, res_Strings2, 7, "intl.accept_languages" }, { CPrefs::DefaultMailCC, STRINGLIST, eStringType, res_Strings2, 8, "mail.default_cc" }, { CPrefs::DefaultNewsCC, STRINGLIST, eStringType, res_Strings2, 9, "news.default_cc" }, { CPrefs::ReplyTo, STRINGLIST, eStringType, res_Strings2, 10, "mail.identity.reply_to" }, { CPrefs::PopID, STRINGLIST, eStringType, res_Strings2, 11, "mail.pop_name" }, { CPrefs::AutoProxyURL, STRINGLIST, eStringType, res_Strings2, 12, "network.proxy.autoconfig_url" }, { CPrefs::MailPassword, STRINGLIST, eStringType, res_Strings2, 13, "mail.pop_password" }, { CPrefs::Ciphers, STRINGLIST, eStringType, res_Strings2, 14, "security.ciphers" }, { CPrefs::EditorAuthor, STRINGLIST, eStringType, res_Strings2, 15, "editor.author" }, { CPrefs::EditorNewDocTemplateLocation, STRINGLIST, eStringType, res_Strings2, 16, "editor.template_location" }, { CPrefs::EditorBackgroundImage, STRINGLIST, eStringType, res_Strings2, 17, "editor.background_image" }, { CPrefs::PublishLocation, STRINGLIST, eStringType, res_Strings2, 18, "editor.publish_location" }, { CPrefs::PublishBrowseLocation, STRINGLIST, eStringType, res_Strings2, 19, "editor.publish_browse_location" }, { CPrefs::PublishHistory0, STRINGLIST, eStringType, res_Strings2, 20, "editor.publish_history_0" }, { CPrefs::PublishHistory1, STRINGLIST, eStringType, res_Strings2, 21, "editor.publish_history_1" }, { CPrefs::PublishHistory2, STRINGLIST, eStringType, res_Strings2, 22, "editor.publish_history_2" }, { CPrefs::PublishHistory3, STRINGLIST, eStringType, res_Strings2, 23, "editor.publish_history_3" }, { CPrefs::PublishHistory4, STRINGLIST, eStringType, res_Strings2, 24, "editor.publish_history_4" }, { CPrefs::PublishHistory5, STRINGLIST, eStringType, res_Strings2, 25, "editor.publish_history_5" }, { CPrefs::PublishHistory6, STRINGLIST, eStringType, res_Strings2, 26, "editor.publish_history_6" }, { CPrefs::PublishHistory7, STRINGLIST, eStringType, res_Strings2, 27, "editor.publish_history_7" }, { CPrefs::PublishHistory8, STRINGLIST, eStringType, res_Strings2, 28, "editor.publish_history_8" }, { CPrefs::PublishHistory9, STRINGLIST, eStringType, res_Strings2, 29, "editor.publish_history_9" }, { CPrefs::DefaultPersonalCertificate, STRINGLIST, eStringType, res_Strings2, 30, "security.default_personal_cert" }, // Booleans { CPrefs::DelayImages, STRINGLIST, eBooleanType, res_StringsBoolean, 1, "browser.delay_images"}, { CPrefs::AnchorUnderline, STRINGLIST, eBooleanType, res_StringsBoolean, 2, "browser.underline_anchors"}, { CPrefs::ShowAllNews, STRINGLIST, eBooleanType, res_StringsBoolean, 3}, { CPrefs::UseFancyFTP, STRINGLIST, eBooleanType, res_StringsBoolean, 4}, { CPrefs::UseFancyNews, STRINGLIST, eBooleanType, res_StringsBoolean, 5, "news.fancy_listing" }, { CPrefs::ShowToolbar, STRINGLIST, eBooleanType, res_StringsBoolean, 6, "browser.chrome.show_toolbar"}, { CPrefs::ShowStatus, STRINGLIST, eBooleanType, res_StringsBoolean, 7, "browser.chrome.show_status_bar"}, { CPrefs::ShowURL, STRINGLIST, eBooleanType, res_StringsBoolean, 8, "browser.chrome.show_url_bar"}, { CPrefs::LoadHomePage, STRINGLIST, eBooleanType, res_StringsBoolean, 9, "browser.startup.autoload_homepage" }, { CPrefs::ExpireNever, STRINGLIST, eBooleanType, res_StringsBoolean, 10, "browser.never_expire"}, { CPrefs::DisplayWhileLoading, STRINGLIST, eBooleanType, res_StringsBoolean,11, "browser.display_while_loading"}, { CPrefs::CustomLinkColors, STRINGLIST, eBooleanType, res_StringsBoolean, 12, "browser.custom_link_color"}, { CPrefs::ShowDirectory, STRINGLIST, eBooleanType, res_StringsBoolean, 13, "browser.chrome.show_directory_buttons" }, { CPrefs::AgreedToLicense, STRINGLIST, eBooleanType, res_StringsBoolean, 14, "browser.startup.agreed_to_licence" }, { CPrefs::EnteringSecure, STRINGLIST, eBooleanType, res_StringsBoolean, 15, "security.warn_entering_secure"}, { CPrefs::LeavingSecure, STRINGLIST, eBooleanType, res_StringsBoolean, 16, "security.warn_leaving_secure"}, { CPrefs::ViewingMixed, STRINGLIST, eBooleanType, res_StringsBoolean, 17, "security.warn_viewing_mixed"}, { CPrefs::SubmittingInsecure, STRINGLIST, eBooleanType, res_StringsBoolean, 18, "security.warn_submit_insecure"}, { CPrefs::ShowSecurity, STRINGLIST, eBooleanType, res_StringsBoolean, 19, "browser.chrome.show_security_bar"}, { CPrefs::CustomVisitedColors,STRINGLIST, eBooleanType, res_StringsBoolean, 20, "browser.custom_visited_color"}, { CPrefs::CustomTextColors, STRINGLIST, eBooleanType, res_StringsBoolean, 21, "browser.custom_text_color"}, { CPrefs::UseDocumentColors, STRINGLIST, eBooleanType, res_StringsBoolean, 22, "browser.use_document_colors"}, { CPrefs::AutoDetectEncoding, STRINGLIST, eBooleanType, res_StringsBoolean, 23, "intl.auto_detect_encoding"}, { CPrefs::UseSigFile, STRINGLIST, eBooleanType, res_StringsBoolean, 24, "mail.use_signature_file"}, { CPrefs::StrictlyMIME, STRINGLIST, eBooleanType, res_StringsBoolean, 25, "mail.strictly_mime" }, { CPrefs::UseUtilityBackground, STRINGLIST, eBooleanType, res_StringsBoolean, 26, "browser.mac.use_utility_pattern"}, { CPrefs::MailUseFixedWidthFont, STRINGLIST, eBooleanType, res_StringsBoolean, 27, "mail.fixed_width_messages"}, { CPrefs::UseMailFCC, STRINGLIST, eBooleanType, res_StringsBoolean, 28, "mail.use_fcc"}, { CPrefs::UseNewsFCC, STRINGLIST, eBooleanType, res_StringsBoolean, 29, "news.use_fcc"}, { CPrefs::LimitMessageSize, STRINGLIST, eBooleanType, res_StringsBoolean, 30, "mail.limit_message_size"}, { CPrefs::LeaveMailOnServer, STRINGLIST, eBooleanType, res_StringsBoolean, 31, "mail.leave_on_server" }, { CPrefs::MailCCSelf, STRINGLIST, eBooleanType, res_StringsBoolean, 32, "mail.cc_self"}, { CPrefs::NewsCCSelf, STRINGLIST, eBooleanType, res_StringsBoolean, 33, "news.cc_self"}, { CPrefs::BiffOn, STRINGLIST, eBooleanType, res_StringsBoolean, 34, "mail.check_new_mail"}, { CPrefs::UseMozPassword, STRINGLIST, eBooleanType, res_StringsBoolean, 35}, { CPrefs::ThreadMail, STRINGLIST, eBooleanType, res_StringsBoolean, 36, "mail.thread_mail"}, { CPrefs::ThreadNews, STRINGLIST, eBooleanType, res_StringsBoolean, 37, "news.thread_news"}, { CPrefs::UseInlineViewSource,STRINGLIST, eBooleanType, res_StringsBoolean, 38 }, { CPrefs::AutoQuoteOnReply, STRINGLIST, eBooleanType, res_StringsBoolean, 39, "mail.auto_quote"}, { CPrefs::RememberMailPassword, STRINGLIST, eBooleanType, res_StringsBoolean, 40, "mail.remember_password"}, { CPrefs::DefaultMailDelivery, STRINGLIST, eBooleanType, res_StringsBoolean, 41, "mail.deliver_immediately"}, { CPrefs::EnableJavascript, STRINGLIST, eBooleanType, res_StringsBoolean, 42, "javascript.enabled" }, { CPrefs::ShowToolTips, STRINGLIST, eBooleanType, res_StringsBoolean, 43, "browser.mac.show_tool_tips"}, { CPrefs::UseInternetConfig, STRINGLIST, eBooleanType, res_StringsBoolean, 44, "browser.mac.use_internet_config"}, { CPrefs::EnableJava, STRINGLIST, eBooleanType, res_StringsBoolean, 45, "security.enable_java" }, { CPrefs::AcceptCookies, STRINGLIST, eBooleanType, res_StringsBoolean, 46, "network.cookie.warnAboutCookies" }, { CPrefs::UseEmailAsPassword, STRINGLIST, eBooleanType, res_StringsBoolean, 47, "security.email_as_ftp_password" }, { CPrefs::SubmitFormsByEmail, STRINGLIST, eBooleanType, res_StringsBoolean, 48, "security.submit_email_forms" }, { CPrefs::AllowSSLDiskCaching, STRINGLIST, eBooleanType, res_StringsBoolean, 49, "browser.cache.disk_cache_ssl" }, { CPrefs::EnableSSLv2, STRINGLIST, eBooleanType, res_StringsBoolean, 50, "security.enable_ssl2" }, { CPrefs::EnableSSLv3, STRINGLIST, eBooleanType, res_StringsBoolean, 51, "security.enable_ssl3" }, { CPrefs::EnableActiveScrolling, STRINGLIST, eBooleanType, res_StringsBoolean, 52, "browser.mac.active_scrolling" }, #ifdef FORTEZZA { CPrefs::FortezzaTimeoutOn, STRINGLIST, eBooleanType, res_StringsBoolean, 0 }, #endif #ifdef EDITOR { CPrefs::EditorUseCustomColors, STRINGLIST, eBooleanType, res_StringsBoolean, 53, "editor.use_custom_colors" }, { CPrefs::EditorUseBackgroundImage, STRINGLIST, eBooleanType, res_StringsBoolean, 54, "editor.use_background_image" }, { CPrefs::PublishMaintainLinks, STRINGLIST, eBooleanType, res_StringsBoolean, 55, "editor.publish_keep_links" }, { CPrefs::PublishKeepImages, STRINGLIST, eBooleanType, res_StringsBoolean, 56, "editor.publish_keep_images" }, { CPrefs::ShowCopyright, STRINGLIST, eBooleanType, res_StringsBoolean, 57, "editor.show_copyright" }, { CPrefs::ShowFileEditToolbar, STRINGLIST, eBooleanType, res_StringsBoolean, 58 }, { CPrefs::ShowCharacterToolbar, STRINGLIST, eBooleanType, res_StringsBoolean, 59, "editor.show_character_toolbar" }, { CPrefs::ShowParagraphToolbar, STRINGLIST, eBooleanType, res_StringsBoolean, 60, "editor.show_paragraph_toolbar" }, #endif EDITOR // WARNING: If you add stuff here, the custom.r file (in projector for Browser and MailNews) must match! // Longs { CPrefs::DiskCacheSize, STRINGLIST, eLongType, res_StringsLong, 1, "browser.cache.disk_cache_size"}, { CPrefs::FileSortMethod, STRINGLIST, eLongType, res_StringsLong, 2, "network.file_sort_method"}, { CPrefs::ToolbarStyle, STRINGLIST, eLongType, res_StringsLong, 3, "browser.chrome.toolbar_style"}, { CPrefs::DaysTilExpire, STRINGLIST, eLongType, res_StringsLong, 4, "browser.link_expiration"}, { CPrefs::Connections, STRINGLIST, eLongType, res_StringsLong, 5, "network.max_connections"}, { CPrefs::BufferSize, STRINGLIST, eLongType, res_StringsLong, 6, "network.tcpbufsize"}, { /*unused*/CPrefs::PrintFlags, STRINGLIST, eLongType, res_StringsLong, 7}, { CPrefs::NewsArticlesMax, STRINGLIST, eLongType, res_StringsLong, 8, "news.max_articles"}, { CPrefs::CheckDocuments, STRINGLIST, eLongType, res_StringsLong, 9, "browser.cache.check_doc_frequency"}, { CPrefs::DefaultCharSetID, STRINGLIST, eLongType, res_StringsLong, 10, "intl.character_set"}, { CPrefs::DefaultFontEncoding,STRINGLIST, eLongType, res_StringsLong, 11, "intl.font_encoding"}, { CPrefs::BackgroundColors, STRINGLIST, eLongType, res_StringsLong, 12, "browser.background_option" }, { CPrefs::LicenseVersion, STRINGLIST, eLongType, res_StringsLong, 13, "browser.startup.license_version"}, { CPrefs::MessageFontStyle, STRINGLIST, eLongType, res_StringsLong, 14, "mail.quoted_style"}, { CPrefs::MessageFontSize, STRINGLIST, eLongType, res_StringsLong, 15, "mail.quoted_size"}, { CPrefs::MaxMessageSize, STRINGLIST, eLongType, res_StringsLong, 16, "mail.max_size" }, { CPrefs::TopLeftHeader, STRINGLIST, eLongType, res_StringsLong, 17, "browser.mac.print_header_topleft" }, { CPrefs::TopMidHeader, STRINGLIST, eLongType, res_StringsLong, 31, "browser.mac.print_header_topmid" }, { CPrefs::TopRightHeader, STRINGLIST, eLongType, res_StringsLong, 18, "browser.mac.print_header_topright" }, { CPrefs::BottomLeftFooter, STRINGLIST, eLongType, res_StringsLong, 19, "browser.mac.print_header_botleft" }, { CPrefs::BottomMidFooter, STRINGLIST, eLongType, res_StringsLong, 20, "browser.mac.print_header_botmid" }, { CPrefs::BottomRightFooter, STRINGLIST, eLongType, res_StringsLong, 21, "browser.mac.print_header_botright" }, { CPrefs::PrintBackground, STRINGLIST, eLongType, res_StringsLong, 22, "browser.mac.print_background" }, { CPrefs::ProxyConfig, STRINGLIST, eLongType, res_StringsLong, 23, "network.proxy.type" }, { CPrefs::StartupAsWhat, STRINGLIST, eLongType, res_StringsLong, 24, "browser.startup.default_window"}, { CPrefs::StartupBitfield, STRINGLIST, eLongType, res_StringsLong, 25, "browser.mac.startup_bitfield"}, { CPrefs::BiffTimeout, STRINGLIST, eLongType, res_StringsLong, 26, "mail.check_time"}, { CPrefs::AskMozPassword, STRINGLIST, eLongType, res_StringsLong, 27, "security.ask_for_password"}, { CPrefs::AskMozPassFrequency,STRINGLIST, eLongType, res_StringsLong, 28, "security.password_lifetime"}, { CPrefs::SortMailBy, STRINGLIST, eLongType, res_StringsLong, 29, "mail.sort_by"}, { CPrefs::SortNewsBy, STRINGLIST, eLongType, res_StringsLong, 30, "news.sort_by"}, { CPrefs::NewsPaneConfig, STRINGLIST, eLongType, res_StringsLong, 32, "news.pane_config"}, { CPrefs::MailPaneConfig, STRINGLIST, eLongType, res_StringsLong, 33, "mail.pane_config"}, { CPrefs::MailHeaderDisplay, STRINGLIST, eLongType, res_StringsLong, 34, "mail.show_headers"}, { CPrefs::NewsHeaderDisplay, STRINGLIST, eLongType, res_StringsLong, 35, "news.show_headers"}, { CPrefs::AutoSaveTimeDelay, STRINGLIST, eLongType, res_StringsLong, 36, "editor.auto_save_delay"}, #ifdef FORTEZZA { CPrefs::FortezzaTimeout, STRINGLIST, eLongType, res_StringsLong, 37, "security.fortezza_lifetime" }, #endif // Colors { CPrefs::Black, NOTSAVED, eColorType, 0, 1}, { CPrefs::White, NOTSAVED, eColorType, 0, 1}, { CPrefs::Blue, NOTSAVED, eColorType, 0, 1}, { CPrefs::Magenta, NOTSAVED, eColorType, 0, 1}, { CPrefs::WindowBkgnd, NOTSAVED, eColorType, 0, 1}, // --was res_StringsColor, 1 { CPrefs::Anchor, STRINGLIST, eColorType, res_StringsColor, 2, "browser.anchor_color"}, { CPrefs::Visited, STRINGLIST, eColorType, res_StringsColor, 3, "browser.visited_color"}, { CPrefs::TextFore, STRINGLIST, eColorType, res_StringsColor, 4, "browser.foreground_color"}, { CPrefs::TextBkgnd, STRINGLIST, eColorType, res_StringsColor, 5, "browser.background_color"}, { CPrefs::EditorText, STRINGLIST, eColorType, res_StringsColor, 6, "editor.text_color"}, { CPrefs::EditorLink, STRINGLIST, eColorType, res_StringsColor, 7, "editor.link_color"}, { CPrefs::EditorActiveLink, STRINGLIST, eColorType, res_StringsColor, 8, "editor.active_link_color"}, { CPrefs::EditorFollowedLink, STRINGLIST, eColorType, res_StringsColor, 9, "editor.followed_link_color"}, { CPrefs::EditorBackground, STRINGLIST, eColorType, res_StringsColor, 10, "editor.background_color"}, { CPrefs::Citation, STRINGLIST, eColorType, res_StringsColor, 11, "mail.citation_color"}, // Print record { CPrefs::PrintRecord, PRINTRECORD, ePrintRecordType, res_PrintRecord, 0 }, // Terminator { CPrefs::LastPref, NOTSAVED, eNoType, 0, 0} }; // // Class variables // RGBColor * CPrefs::sColors = NULL; CFolderSpec ** CPrefs::sFileIDs = NULL; THPrint CPrefs::sPrintRec = NULL; CMimeList CPrefs::sMimeTypes; char * CPrefs::sCachePath = NULL; FSSpec CPrefs::sTemporaryFolder; Boolean CPrefs::sRealTemporaryFolder = false; Boolean CPrefs::sViewSourceInline = true; // 0 = no user preference file // 3 = preferences in resource fork // 4 = preferences in data fork short CPrefs::sPrefFileVersion = 3; // // Static variables // // Preference file related static LFile * sPrefFile = NULL; static short sPrefFileResID = refNum_Undefined; static short sAppFileResID = refNum_Undefined; static Boolean sReading = FALSE; // Are we reading the prefs right now? static Boolean sDirty = FALSE; static Boolean sDirtyOnRead = FALSE; // Used to signal saving of preferences // if we need to touch them while reading // // Utility routines // static UInt32 CountPrefsOfType(PrefType type); static LFile* GetFileForPreferences(); /*static*/ Boolean FindDefaultPreferencesFolder( FSSpec& prefFolder, short folderNameID, Boolean createIt, Boolean resolveIt = true ); static OSErr AssertPrefsFileOpen(Int16 privileges); static LO_Color MakeLOColor( const RGBColor& rgbColor ); static OSErr AssurePreferencesSubfolder(pref_Strings whichFolder, FSSpec & folderSpec); // Counts how many preferences of particular type do we have UInt32 CountPrefsOfType(PrefType type) { UInt32 howMany = 0; int i = 0; while(prefLoc[i].prefType != eNoType) if (prefLoc[i++].prefType == type) howMany++; return howMany; } // FindDefaultPreferencesFolder searches the disk for a preferences folder. // If it does not find one, it tries to create it. // It returns false upon complete failure (could not find or create) // Folder lookup sequence: Preferences, Home directory, Desktop // Algorithm: // Look for a folder in folder lookup sequence. // If not found try to create it in the same sequence. Boolean FindDefaultPreferencesFolder( FSSpec& prefFolder, short folderNameID, Boolean createIt, Boolean resolveIt ) { short prefRefNum, deskRefNum; long prefDirID, deskDirID; FSSpec netscapeFolder = CPrefs::GetFilePrototype(CPrefs::NetscapeFolder); OSErr err = FindFolder( kOnSystemDisk, kPreferencesFolderType, kCreateFolder, &prefRefNum, &prefDirID );// Get Pref directory OSErr err2 = FindFolder( kOnSystemDisk, kDesktopFolderType, kCreateFolder, &deskRefNum, &deskDirID ); // ¥ check for presence of MCC folderÉ Boolean foundFolder = FALSE; CStr255 folderName; GetIndString( folderName, 300, folderNameID ); LString::CopyPStr( folderName, prefFolder.name, 32 ); // ¥ in the Preferences folder if ( !foundFolder && ( err == noErr ) && ( CFileMgr::FindWFolderInFolder( prefRefNum, prefDirID, folderName, &prefFolder.vRefNum, &prefFolder.parID) == noErr ) ) foundFolder = TRUE; // ¥Êin the applications folder if ( !foundFolder && ( CFileMgr::FindWFolderInFolder( netscapeFolder.vRefNum, netscapeFolder.parID, folderName, &prefFolder.vRefNum, &prefFolder.parID) == noErr ) ) foundFolder = TRUE; // ¥Êand on the desktop if ( ( !foundFolder ) && ( err2 == noErr ) && ( CFileMgr::FindWFolderInFolder( deskRefNum, deskDirID, folderName, &prefFolder.vRefNum, &prefFolder.parID) == noErr ) ) foundFolder = TRUE; // ¥Êcreate a folder if one does not exist. Go in Folder lookup sequence if ( !foundFolder && createIt ) { // ¥ get the name of the folder out of resources CStr255 folderName; GetIndString( folderName, 300, folderNameID ); OSErr createError; // ¥Êtry the Preferences folder createError = CFileMgr::CreateFolderInFolder( prefRefNum, prefDirID, folderName, &prefFolder.vRefNum, &prefFolder.parID); if ( createError == noErr ) foundFolder = TRUE; else { // ¥Êtry the application's folder createError = CFileMgr::CreateFolderInFolder( netscapeFolder.vRefNum, netscapeFolder.parID, folderName, &prefFolder.vRefNum, &prefFolder.parID); if ( createError == noErr ) foundFolder = TRUE; else { // ¥ try the Desktop createError = CFileMgr::CreateFolderInFolder(deskRefNum, deskDirID, folderName, &prefFolder.vRefNum, &prefFolder.parID); if ( createError == noErr ) foundFolder = TRUE; else foundFolder = FALSE; } } } if (foundFolder && resolveIt) CFileMgr::FolderSpecFromFolderID(prefFolder.vRefNum, prefFolder.parID, prefFolder); return foundFolder; } inline Boolean CPrefs::IsNewPrefFormat(short id) { return prefLoc[id].prefName != nil; } // Returns LFile for the preferences // File might not exist LFile* GetFileForPreferences() { FSSpec prefFileSpec; // ¥Êget the default preferences file name from the application rsrc fork ::GetIndString( prefFileSpec.name, 300, prefFileName ); if ( prefFileSpec.name[0] > 31 ) prefFileSpec.name[0] = 31; FSSpec folderSpec = CPrefs::GetFilePrototype(CPrefs::MainFolder); prefFileSpec.vRefNum = folderSpec.vRefNum; prefFileSpec.parID = folderSpec.parID; CPrefs::sPrefFileVersion = CFileMgr::FileExists(prefFileSpec) ? 3 : 0; // ¥ return a fully specified LFile return new LFile( prefFileSpec ); } // Creates the file if it does not exist static OSErr AssertPrefsFileOpen(Int16 privileges) { Try_ { ThrowIfNil_(sPrefFile); Try_ { sPrefFile->OpenResourceFork(privileges); } Catch_(inErr) { // Create the resource fork if it doesn't exist if (inErr == fnfErr || inErr == eofErr) { sPrefFile->CreateNewFile(emSignature, emPrefsType); sPrefFile->OpenResourceFork(privileges); } // Non-fatal error. We are trying to open prefs twice in a row else if (!((inErr == opWrErr) && (sPrefFile->GetResourceForkRefNum() != refNum_Undefined))) Throw_(inErr); } EndCatch_ sPrefFileResID = sPrefFile->GetResourceForkRefNum(); } Catch_(inErr) { return inErr; } EndCatch_ return noErr; } static void ClosePrefsFile() { Try_ { if (sPrefFile) { if (sPrefFile->GetResourceForkRefNum() != refNum_Undefined) sPrefFile->CloseResourceFork(); if (sPrefFile->GetDataForkRefNum() != refNum_Undefined) sPrefFile->CloseDataFork(); } } Catch_(inErr) { Assert_(FALSE); } EndCatch_ sPrefFileResID = refNum_Undefined; // // Now that the prefs are closed, make sure weÕre // not using some random file (like a plug-in). // CPrefs::UseApplicationResFile(); } #define NON_EXISTENT_NAME "\pNONEXISTENTsj8432903849" // ¥ Makes sure that the folder with a given spec exists inside preferences. // if it is not found, it creates one. static OSErr AssurePreferencesSubfolder(pref_Strings whichFolder, FSSpec & folderSpec) { FSSpec mainSpec = CPrefs::GetFilePrototype(CPrefs::MainFolder); // Find a folder. Create one if necessary ::GetIndString( folderSpec.name, 300, whichFolder ); OSErr err = noErr; if ( CFileMgr::FindWFolderInFolder(mainSpec.vRefNum, mainSpec.parID, folderSpec.name, &folderSpec.vRefNum, &folderSpec.parID) != noErr ) // Not found, must create it err = CFileMgr::CreateFolderInFolder( mainSpec.vRefNum, mainSpec.parID, folderSpec.name, &folderSpec.vRefNum, &folderSpec.parID ); if ( err != noErr ) // Also try application folder for lab settings { mainSpec = CPrefs::GetFilePrototype( CPrefs::NetscapeFolder ); err = CFileMgr::FindWFolderInFolder( mainSpec.vRefNum, mainSpec.parID, folderSpec.name, &folderSpec.vRefNum, &folderSpec.parID ); if ( err != noErr ) err = CFileMgr::CreateFolderInFolder( mainSpec.vRefNum, mainSpec.parID, folderSpec.name, &folderSpec.vRefNum, &folderSpec.parID ); } err = CFileMgr::FolderSpecFromFolderID( folderSpec.vRefNum, folderSpec.parID, folderSpec ); return err; } static CStr255 BuildProxyString(CStr255 host, CStr255 port) { CStr255 ret = host; if ((host.Length() > 0) && (port.Length() > 0)) { ret += ":"; ret += port; } return ret; } static LO_Color MakeLOColor( const RGBColor& rgbColor ) { LO_Color temp; temp.red = rgbColor.red >> 8; temp.green = rgbColor.green >> 8; temp.blue = rgbColor.blue >> 8; return temp; } // Returns TRUE if resource existed // If it does not exist, creates a resource of 0 length static Boolean AssertResourceExist(ResType type, short id) { Handle r = ::Get1Resource(type, id); if (r == NULL) { Handle h = ::NewHandle(0); ThrowIfNil_(h); ::AddResource(h, type, id, CStr255::sEmptyString); ThrowIfResError_(); SInt8 flags = ::HGetState(h); ::HNoPurge(h); ::SetResAttrs(h, ::GetResAttrs(h) | resPurgeable); // Pref resources are purgeable if (type == STRINGLIST) { CStringListRsrc stringList(id); stringList.ClearAll(); } ::HSetState(h, flags); return FALSE; } else return TRUE; } /***************************************************************************** * struct CFolderSpec * Contains specs for the folder and a prototype spec for the file to be * created inside this folder *****************************************************************************/ CFolderSpec::CFolderSpec() { fFolder.vRefNum = fFolder.parID = refNum_Undefined; fFilePrototype.vRefNum = fFilePrototype.parID = refNum_Undefined; } // Sets the specs for this folder. Must figure out the prototype file specs too OSErr CFolderSpec::SetFolderSpec(FSSpec newSpec, int folderID) /* This routine is called for two different sorts of folders, those whose locations are saved in the preferences, and those that are not. For the former, |newSpec| is constructed from the saved location. For the latter, it is uninitialized. */ { FSSpec debugSpec; OSErr settingError; settingError = FSMakeFSSpec( newSpec.vRefNum, newSpec.parID, newSpec.name, &debugSpec); if ( settingError != noErr ) { sDirtyOnRead = TRUE; Try_ { switch ( (CPrefs::PrefEnum)folderID ) { case CPrefs::DownloadFolder: ThrowIfOSErr_( FindFolder( kOnSystemDisk, kDesktopFolderType, kCreateFolder, &newSpec.vRefNum, &newSpec.parID )); ThrowIfOSErr_( CFileMgr::FolderSpecFromFolderID(newSpec.vRefNum, newSpec.parID, newSpec)); break; case CPrefs::NewsFolder: { #ifdef MOZ_MAIL_NEWS OSErr err = AssurePreferencesSubfolder(newsFolderName, newSpec); #else OSErr err = fnfErr; // Brutal hard coded err for a world without mail/news #endif //MOZ_MAIL_NEWS if ( err != noErr ) { fFolder.vRefNum = fFolder.parID = fFilePrototype.vRefNum = fFilePrototype.parID = 0; return err; } } break; case CPrefs::SecurityFolder: { OSErr err = AssurePreferencesSubfolder(securityFolderName, newSpec); if ( err != noErr ) { fFolder.vRefNum = fFolder.parID = fFilePrototype.vRefNum = fFilePrototype.parID = 0; return err; } } break; case CPrefs::DiskCacheFolder: // Caching folder. By default it is inside the main folder. { OSErr err = AssurePreferencesSubfolder(cacheFolderName, newSpec); if ( err != noErr ) { fFolder.vRefNum = fFolder.parID = fFilePrototype.vRefNum = fFilePrototype.parID = 0; return err; } } break; case CPrefs::SARCacheFolder: // Archive Cache folder. By default it is inside the main folder. { OSErr err = AssurePreferencesSubfolder(sarCacheFolderName, newSpec); if ( err != noErr ) { fFolder.vRefNum = fFolder.parID = fFilePrototype.vRefNum = fFilePrototype.parID = 0; return err; } } break; case CPrefs::MailFolder: { #ifdef MOZ_MAIL_NEWS OSErr err = AssurePreferencesSubfolder(mailFolderName, newSpec); #else OSErr err = fnfErr; // Brutal hard coded err for a world without mail/news #endif //MOZ_MAIL_NEWS if ( err != noErr ) { fFolder.vRefNum = fFolder.parID = fFilePrototype.vRefNum = fFilePrototype.parID = 0; return err; } } break; case CPrefs::NetHelpFolder: { /* [scc:] Essentially this same code appears in uapp.cp for resolving the "Essential Files" folder. It should be broken out into a separate static member function of |CFileMgr| a la FindWFolderInFolder. */ FSSpec netscapeFolderSpec = CPrefs::GetFolderSpec(CPrefs::NetscapeFolder); // Build a partial path to the guts folder starting from a folder we know (the Netscape folder) Str255 partialPath; { // Get the name of the guts folder Str255 helpFolderName; GetIndString(helpFolderName, 300, nethelpFolderName); // partialPath = ":" + netscapeFolderSpec.name + ":" + gutsFolderName; // ( this may _look_ cumbersome, but it's really the most space and time efficient way to catentate 4 pstrings ) int dest=0; partialPath[++dest] = ':'; for ( int src=0; srcioNamePtr = (StringPtr)&fFilePrototype.name; dipb->ioVRefNum = fFolder.vRefNum; dipb->ioFDirIndex = 0; dipb->ioDrDirID = fFolder.parID; OSErr err = PBGetCatInfoSync(&cinfo); fFilePrototype.name[0] = 0; // there are places where a path is made from the raw prototype! if (err == noErr) { fFilePrototype.vRefNum = dipb->ioVRefNum; fFilePrototype.parID = dipb->ioDrDirID; } else { fFilePrototype.vRefNum = 0; fFilePrototype.parID = 0; } return settingError; } Boolean CFolderSpec::Exists() { CStr63 name; CStr63 doesntExist( NON_EXISTENT_NAME ); name = fFolder.name; return ( name != doesntExist ); } //---------------------------------------------------------------------------------------- void CPrefs::Initialize() // Initialize all statics // This must be called before any other preference routines. // OK, so would somebody please add a comment as to why this can't be done in the // constructor? //---------------------------------------------------------------------------------------- { UInt32 howMany = CountPrefsOfType(eFileSpecType); sFileIDs = (CFolderSpec **)XP_CALLOC(1, howMany * sizeof(CFolderSpec *)); ThrowIfNil_( sFileIDs ); for (int i=0; iGetSpecifier(prefSpec); char* prefFile = CFileMgr::PathNameFromFSSpec(prefSpec, true); // Note: we call PREF_Init(NULL) in main() in uapp.cp; // the call below does not re-initialize but loads the user prefs file. if ( PREF_Init(prefFile) == JS_TRUE ) { sPrefFileVersion = 4; } XP_FREE(prefFile); // Read optional profile.cfg (per-profile configuration) file FSSpec profileConfig; profileConfig.vRefNum = prefSpec.vRefNum; profileConfig.parID = prefSpec.parID; LString::CopyPStr("\pprofile.cfg", profileConfig.name, 32); if (CFileMgr::FileExists(profileConfig)) { PREF_ReadLockFile( CFileMgr::PathNameFromFSSpec(profileConfig, true) ); } // Read the lock/config file, looking in both the // Users folder and the Essential Files folder Boolean lockLoaded = false; lockSpec = CPrefs::GetFilePrototype(CPrefs::RequiredGutsFolder); GetIndString(lockSpec.name, 300, configFile); if (!CFileMgr::FileExists(lockSpec)) { lockSpec = CPrefs::GetFilePrototype(CPrefs::UsersFolder); GetIndString(lockSpec.name, 300, configFile); } if (CFileMgr::FileExists(lockSpec)) { char* lockFile = CFileMgr::PathNameFromFSSpec(lockSpec, true); if (lockFile) { int lockErr = PREF_ReadLockFile(lockFile); lockLoaded = (lockErr == PREF_NOERROR); XP_FREE(lockFile); if (lockErr == PREF_BAD_LOCKFILE) { CStr255 errStr; GetIndString(errStr, CUserProfile::kProfileStrings, CUserProfile::kInvalidConfigFile); ErrorManager::PlainAlert(errStr); return eAbort; } } } // The presence of a 'Lock' application resource means // we should abort if the lock file failed to load if ( !lockLoaded && ::GetResource('Lock', 128) != nil ) { CStr255 errStr; GetIndString(errStr, CUserProfile::kProfileStrings, CUserProfile::kConfigFileError); ErrorManager::PlainAlert(errStr); return eAbort; } OpenAnimationFile(lockSpec, profileConfig); ReadAllPreferences(); { // Connect to Internet Config, passing path of current // profile directory. This allows each profile to // contain its own IC Preferences file. // We do not want a stupid break to source debugger every time StValueChanger okayToFail(UDebugging::gDebugThrow, debugAction_Nothing); CInternetConfigInterface::ConnectToInternetConfig(/*&prefSpec*/); } RegisterPrefCallbacks(); // ¥Êhandle the upgrade path that involves us telling the user // that we're creating "Netscape Users", etc. // (I don't know why this is handled here) if ( result == eNeedUpgrade ) { FSSpec prefsFolder; FSSpec oldPrefsFolder; ProfileErr profResult; oldPrefsFolder = CPrefs::GetFolderSpec( CPrefs::MainFolder ); profResult = CUserProfile::HandleUpgrade( prefsFolder, &oldPrefsFolder ); if ( profResult == eOK || profResult == eRunAccountSetup ) { // ¥ user OK'ed it, so we set the prefs folder to point to the new // place now CPrefs::SetFolderSpec( prefsFolder, CPrefs::MainFolder ); } else // ¥ user chose to Quit return eAbort; if ( profResult == eRunAccountSetup ) result = eRunAccountSetup; } // --EKit: Prevent failover if config is locked on auto-proxy if ( IsLocked(ProxyConfig) && GetLong(ProxyConfig) == PROXY_STYLE_AUTOMATIC ) { NET_SetNoProxyFailover(); } return result; } void CPrefs::DoWrite() { if (sPrefFile == NULL) sPrefFile = GetFileForPreferences(); if (sPrefFile == NULL) return; if (!sDirty) return; WriteAllPreferences(); } // Reads in all the preferences void CPrefs::ReadAllPreferences() { sReading = TRUE; try { sDirtyOnRead = FALSE; AssertPrefsFileOpen(fsRdPerm); int i = FIRSTPREF; while(prefLoc[i].prefID != LastPref) ReadPreference((PrefEnum)i++); ReadMimeTypes(); ReadCharacterEncodings(); CNotifierRegistry::ReadProtocolHandlers(); sDirty = sDirtyOnRead; // Needs to be done after all prefs have been read NET_SelectProxyStyle( (NET_ProxyStyle) GetLong( ProxyConfig) ); } catch(...) { ClosePrefsFile(); sReading = FALSE; throw; } sReading = FALSE; ClosePrefsFile(); } void CPrefs::WriteAllPreferences() { Try_ { ThrowIfOSErr_(AssertPrefsFileOpen(fsRdWrPerm)); // --xp prefs FSSpec prefSpec; sPrefFile->GetSpecifier(prefSpec); char* prefFile = CFileMgr::PathNameFromFSSpec(prefSpec, true); int err = PREF_SavePrefFileAs(prefFile); ThrowIfOSErr_(err); // -- WritePreference now skips all prefs except for print record WritePreference( CPrefs::PrintRecord ); CNotifierRegistry::WriteProtocolHandlers(); AssertResourceExist(REVISION, REVISION_RES_ID); Handle res = ::Get1Resource( REVISION, REVISION_RES_ID ); if (res && *res) { SInt8 flags = ::HGetState(res); ::HNoPurge(res); if ((::GetHandleSize(res) < sizeof(long)) || (*(long *)*res != PREF_REVISION_NUMBER)) { ::SetHandleSize(res, sizeof(long)); ThrowIfMemError_(); *(long *)*res = PREF_REVISION_NUMBER; ::ChangedResource(res); ::WriteResource(res); } ::HSetState(res, flags); } } Catch_(inErr) { ClosePrefsFile(); ErrorManager::PlainAlert( mPREFS_CANNOT_WRITE ); ErrorManager::ErrorNotify(inErr, GetPString(THE_ERROR_WAS)); } EndCatch_ ClosePrefsFile(); } // Gets the right resource // First tries the pref file resource fork, // On fail, try the application resource fork // If they both fail, throw void CPrefs::ReadPreference(short index) { switch(prefLoc[index].resType) { case NOTSAVED: InitializeUnsavedPref(index); break; case STRINGLIST: { CStr255 s; if ( sPrefFileVersion != 3 && IsNewPrefFormat(index) ) { // --xp prefs temp: Do this to send init prefs values to // the right modules-- // to be REPLACED by modules initing own prefs via callbacks PostInitializePref(prefLoc[index].prefID, true); return; } // Otherwise, read from old-format Prefs file if (UsePreferencesResFile()) { Handle stringListHandle = ::Get1Resource(STRINGLIST, prefLoc[index].resID); if (stringListHandle && *stringListHandle) { if (::GetHandleSize(stringListHandle) >= sizeof(short)) { CStringListRsrc stringList(prefLoc[index].resID); if (stringList.CountStrings() >= prefLoc[index].refCon && prefLoc[index].refCon > 0) // We are OK, we have a string { stringList.GetString(prefLoc[index].refCon, s); goto postprocessstring; } } else { ::RemoveResource(stringListHandle); ::DisposeHandle(stringListHandle); } } } // drop through sDirtyOnRead = TRUE; postprocessstring: switch (prefLoc[index].prefType) { case eStringType: // Convert 3.0 ports from strings to ints switch (prefLoc[index].prefID) { case FTPProxyPort: case GopherProxyPort: case HTTPProxyPort: case WAISProxyPort: case SSLProxyPort: case SOCKSPort: Int32 value; if (sscanf(s, "%ld", &value) == 1) SetLong(value, prefLoc[index].prefID); break; default: SetString(s, prefLoc[index].prefID); } break; case eBooleanType: Boolean bvalue; if (strcasecomp(s, "FALSE") == 0) bvalue = false; else if (strcasecomp(s, "TRUE") == 0) bvalue = true; else break; switch (prefLoc[index].prefID) { case EnableJava: case EnableJavascript: bvalue = ! bvalue; break; case UseInlineViewSource: sViewSourceInline = bvalue; break; } SetBoolean(bvalue, prefLoc[index].prefID); break; case eLongType: Int32 value; if (sscanf(s, "%ld", &value) != 1) break; // Magic conversions of 3.0 prefs to 4.0 units if (prefLoc[index].prefID == PrintBackground) SetBoolean (value != 0, PrintBackground); // was a long, now a boolean else { switch (prefLoc[index].prefID) { case DiskCacheSize: value = value / DISK_CACHE_SCALE; // was in bytes, now in K break; case BufferSize: value = value * BUFFER_SCALE; // was in K, now in bytes break; #ifdef MOZ_MAILNEWS case MailHeaderDisplay: switch (value) { // see msgprefs.cpp case SHOW_ALL_HEADERS: value = 2; break; case SHOW_SOME_HEADERS: value = 1; break; case SHOW_MICRO_HEADERS: value = 0; break; } break; #endif } SetLong(value, prefLoc[index].prefID); } break; case eColorType: long r,g,b; RGBColor c; if (sscanf(s, "%ld %ld %ld", &r, &g, &b) != 3) break; c.red = r; c.green = g; c.blue = b; // Conversion from 3.0 colors. Use default color if // the corresponding "use custom" box wasn't checked. switch (prefLoc[index].prefID) { case TextBkgnd: if (GetLong(BackgroundColors) != CUSTOM_BACKGROUND) c = GetColor(WindowBkgnd); break; case TextFore: if (!GetBoolean(CustomTextColors)) c = GetColor(Black); break; case Anchor: if (!GetBoolean(CustomLinkColors)) c = GetColor(Blue); break; case Visited: if (!GetBoolean(CustomVisitedColors)) c = GetColor(Magenta); break; } SetColor(c, prefLoc[index].prefID); break; default: Assert_(FALSE);; } } break; case ALIASREC: { // Read old alias pref from resource FSSpec folder; folder.vRefNum = folder.parID = refNum_Undefined; LString::CopyPStr(NON_EXISTENT_NAME, folder.name, 32); AliasHandle a = NULL; Boolean gotAlias = false; Boolean fromResource = false; // XP prefs: Read alias as binary type if ( sPrefFileVersion != 3 && IsNewPrefFormat(index) ) { int size; void* alias; if (PREF_CopyBinaryPref( prefLoc[index].prefName, &alias, &size ) == 0) { PtrToHand(alias, &(Handle) a, size); XP_FREE(alias); } } else if (UsePreferencesResFile()) { a = (AliasHandle)::Get1Resource( ALIASREC, prefLoc[index].resID ); fromResource = true; } if (a && *a) { Boolean changed; SInt8 flags = ::HGetState((Handle) a); ::HNoPurge((Handle )a); OSErr err = ::ResolveAlias( NULL, a, &folder, &changed ); gotAlias = (err == noErr); if (!gotAlias) folder.vRefNum = folder.parID = refNum_Undefined; ::HSetState((Handle) a, flags); if (fromResource) { if (gotAlias) { // 3.0 format alias: convert to an xp preference ::HLock((Handle) a); PREF_SetBinaryPref( prefLoc[index].prefName, (void*) *a, GetHandleSize((Handle) a) ); ::HUnlock((Handle) a); } } else { ::DisposeHandle((Handle) a); } } SetFolderSpec(folder, prefLoc[index].prefID); // If there is no user preference value for the alias, or the alias // is invalid, then SetFolderSpec fills in the default location. // We need to reflect it into a default xp pref: if (!gotAlias) { folder = GetFolderSpec(prefLoc[index].prefID); AliasHandle aliasH; OSErr err = NewAlias(nil, &folder, &aliasH); if (err == noErr) { Size bytes = GetHandleSize((Handle) aliasH); HLock((Handle) aliasH); PREF_SetDefaultBinaryPref( prefLoc[index].prefName, *aliasH, bytes ); DisposeHandle((Handle) aliasH); } } } break; case PRINTRECORD: { if (UsePreferencesResFile()) { Handle printHandle = ::Get1Resource( PRINTRECORD, prefLoc[index].resID); if ( printHandle ) { if ( !*printHandle ) ::LoadResource( printHandle ); if ( *printHandle && (::GetHandleSize(printHandle) >= sizeof(TPrint))) { ::HNoPurge( printHandle ); ::DetachResource( printHandle ); sPrintRec = (THPrint)printHandle; } } } if (sPrintRec == NULL) Try_ { sPrintRec = UPrintingMgr::GetDefaultPrintRecord(); } Catch_(inErr) { } EndCatch_ } break; default: Assert_(FALSE);; } } // Writes the resource // Make sure that we are only saving into pref file resource fork, void CPrefs::WritePreference(short index) { ThrowIf_(!UsePreferencesResFile()); switch(prefLoc[index].resType) { case ALIASREC: { // --ML ?? this comment: // Do not save TemporaryFolder special case. Do not save it if // it points to the temp directory } break; case PRINTRECORD: { if (sPrintRec) { AssertResourceExist(PRINTRECORD, prefLoc[index].resID); Handle printHandle = ::Get1Resource( PRINTRECORD, prefLoc[index].resID ); ThrowIfNil_(printHandle); ThrowIfNil_(*printHandle); SInt8 flags = ::HGetState(printHandle); ::HNoPurge(printHandle); StHandleLocker lock((Handle)sPrintRec); ThrowIfOSErr_(::PtrToXHand(*sPrintRec, printHandle, sizeof(TPrint))); ::ChangedResource( printHandle ); ::WriteResource(printHandle); ::HSetState(printHandle, flags); } } break; default: break; } } // NOTE: the caller of this method is responsible for disposing of the // returned window data handle Handle CPrefs::ReadWindowData( short resID ) { Handle theWindowData = NULL; try { AssertPrefsFileOpen( fsRdPerm ); if (UsePreferencesResFile()) { theWindowData = ::Get1Resource(WINDOWREC, resID); if (theWindowData) { ::HNoPurge(theWindowData); ::DetachResource(theWindowData); ThrowIfResError_(); } } } catch (...) { if (theWindowData != NULL) ::ReleaseResource(theWindowData); theWindowData = NULL; } ClosePrefsFile(); return theWindowData; } void CPrefs::WriteWindowData( Handle data, short resID ) { try { ThrowIfOSErr_(AssertPrefsFileOpen(fsRdWrPerm)); UsePreferencesResFile(); AssertResourceExist( WINDOWREC, resID ); Handle resHandle = ::Get1Resource( WINDOWREC, resID ); ThrowIfNil_( resHandle ); ThrowIfNil_( *resHandle ); SInt8 flags = ::HGetState(resHandle); ::HNoPurge(resHandle); long size; size = ::GetHandleSize( data ); ::SetHandleSize( resHandle, size ); ThrowIfMemError_(); ::BlockMoveData( *data, *resHandle, size ); ::ChangedResource(resHandle); ::WriteResource(resHandle); ::HSetState(resHandle, flags); } catch (...) { } ClosePrefsFile(); } Boolean CPrefs::UsePreferencesResFile() { if (sPrefFileResID != refNum_Undefined) { ::UseResFile(sPrefFileResID); return TRUE; } return FALSE; } Boolean CPrefs::UseApplicationResFile() { ::UseResFile(LMGetCurApRefNum()); return TRUE; } // Find the Preference folder -- Three cases: // 1. User launched a specific prefs file. Its parent is the prefs folder. // 2. Single profile found. Prefs folder is the default. // 3. Multiple profiles. Prompt user for prefs folder. CPrefs::PrefErr CPrefs::InitPrefsFolder(short fileType) { PrefErr result = eOK; Boolean showProfiles = false; FSSpec prefsFolder, prefSpec; CUserProfile::InitUserProfiles(); // A "profile" fileType means the Profile Manager was launched, // so always show the profile selection dialog. if (fileType == FILE_TYPE_PROFILES) showProfiles = true; // Actually for the time being we always want the Profile Manager to appear so just set // showProfiles to true. Fix things when we get the external app to invoke the Profile // Manager back into the public source tree. showProfiles = true; FSSpec usersFolder; Boolean foundPrefs = FindDefaultPreferencesFolder(usersFolder, usersFolderName, true); if (!foundPrefs) { ErrorManager::PlainAlert(mPREFS_CANNOT_CREATE_PREFS_FOLDER); return eAbort; } CPrefs::SetFolderSpec( usersFolder, CPrefs::UsersFolder ); if ( sPrefFile ) { sPrefFile->GetSpecifier( prefSpec ); ThrowIfOSErr_( CFileMgr::FolderSpecFromFolderID( prefSpec.vRefNum, prefSpec.parID, prefsFolder ) ); } else { ProfileErr err; usersFolder = CPrefs::GetFilePrototype( CPrefs::UsersFolder ); if ( fileType != STARTUP_TYPE_NETPROFILE) // ¥Êhandle user profile here err = CUserProfile::GetUserProfile( usersFolder, prefsFolder, showProfiles, fileType ); else err = CUserProfile::CreateNetProfile(usersFolder, prefsFolder); // ¥ first time through we get the "eNeedUpgrade" error if ( err == eNeedUpgrade ) { result = eNeedUpgrade; // ¥Êpoint to the old 3.0 Netscape Ä folder // (but don't create it if it doesn't exist). if ( !FindDefaultPreferencesFolder( prefsFolder, prefFolderName, false ) ) { // ¥ no Netscape Ä, so do the upgrade right now // !! if returns error then need to Quit... sPrefFileVersion = 0; err = CUserProfile::HandleUpgrade( prefsFolder ); if ( err == eOK ) result = eOK; else if ( err == eRunAccountSetup ) result = eRunAccountSetup; // ¥Êare we having fun yet? else result = eAbort; } } else if ( err == eRunAccountSetup ) result = eRunAccountSetup; else if ( (err == eUserCancelled) || (err == eUnknownError) ) result = eAbort; } CPrefs::SetFolderSpec( prefsFolder, CPrefs::MainFolder ); return result; } /* FindRequiredGutsFolder Algorithm (given definitons of usersFolder, mainFolder, netscapeFolder) inLaunchWithPrefs is true if user double clicked on a preferences folder. if inLaunchWithPrefs try to find in the mainFolder (parent of folder user clicked on) try to find in the netscapeFolder (where app is) try to find in the usersFolder (where the user prefs directories are) if !inLaunchWithPrefs try to find in the app folder try to find in the Netscape Ä folder (ie prefs) */ Boolean CPrefs::FindRequiredGutsFolder(Boolean inLaunchWithPrefs) { FSSpec usersFolder; // always the "Netscape Users" in the preferences folder FSSpec mainFolder; // if inLaunchWithPrefs, parent of prefs folder, otherwise "Netscape Ä" FSSpec netscapeFolder; // the folder containing the app FSSpec gutsFolder; OSErr tempErr; ::GetIndString( gutsFolder.name, 300, prefRequiredGutsName ); // really get directory IDs for these folders (not parIDs) netscapeFolder = GetFilePrototype(NetscapeFolder); usersFolder = GetFilePrototype(UsersFolder); mainFolder = GetFilePrototype(MainFolder); // see note below, but basically we are using parID of the gutsFolder // and of the parent foldres to mean the IDs of the folders if (inLaunchWithPrefs) { tempErr = CFileMgr::FindWFolderInFolder(mainFolder.vRefNum, mainFolder.parID, gutsFolder.name ,&gutsFolder.vRefNum, &gutsFolder.parID); if (noErr != tempErr) { tempErr = CFileMgr::FindWFolderInFolder(netscapeFolder.vRefNum, netscapeFolder.parID, gutsFolder.name ,&gutsFolder.vRefNum, &gutsFolder.parID); if (noErr != tempErr) { tempErr = CFileMgr::FindWFolderInFolder(usersFolder.vRefNum, usersFolder.parID, gutsFolder.name ,&gutsFolder.vRefNum, &gutsFolder.parID); } } } else { tempErr = CFileMgr::FindWFolderInFolder(netscapeFolder.vRefNum, netscapeFolder.parID, gutsFolder.name ,&gutsFolder.vRefNum, &gutsFolder.parID); if (noErr != tempErr) { tempErr = CFileMgr::FindWFolderInFolder(mainFolder.vRefNum, mainFolder.parID, gutsFolder.name ,&gutsFolder.vRefNum, &gutsFolder.parID); } } // return false in case of error if (noErr == tempErr) { FSSpec toSet; // so what we really got from FindWFolderInFolder is the directory ID // (a shorthand reference to a specification). Now lets convert it // into a proper specification for a folder CFileMgr::FolderSpecFromFolderID(gutsFolder.vRefNum, gutsFolder.parID, toSet); SetFolderSpec(toSet, CPrefs::RequiredGutsFolder); return (true); } else { return (false); } } // All preferences designated "NOTSAVED" are initialized here void CPrefs::InitializeUnsavedPref(short index) { switch(prefLoc[index].prefID) { case NetscapeFolder: break; // Initialized automatically on startup case MainFolder: case UsersFolder: case RequiredGutsFolder: break; // Moved to InitPrefsFolder case NewsFolder: case SecurityFolder: case SARCacheFolder: case NetHelpFolder: FSSpec folder; folder.vRefNum = folder.parID = refNum_Undefined; SetFolderSpec(folder, prefLoc[index].prefID); break; case WindowBkgnd: RGBColor c; c.red = c.green = c.blue = 0xC0C0; SetColor(c, prefLoc[index].prefID); break; case Black: c.red = c.green = c.blue = 0; SetColor(c, prefLoc[index].prefID); break; case White: c.red = c.green = c.blue = 0xFFFF; SetColor(c, prefLoc[index].prefID); break; case Blue: c.red = c.green = 0; c.blue = 0xFFFF; SetColor(c, prefLoc[index].prefID); break; case Magenta: c.red = 0x5500; c.green = 0x1A00; c.blue = 0x8B00; SetColor(c, prefLoc[index].prefID); break; default: Assert_(FALSE);; // Unsaved prefs need to be initialized statically } } void CPrefs::SetModified() { sDirty = TRUE; } // Strings Boolean CPrefs::SetString(const char* newString, PrefEnum id) { Boolean changed = TRUE; if ( IsNewPrefFormat(id) ) { changed = PREF_SetCharPref( prefLoc[id].prefName, newString ); } PostInitializePref(id, changed); return changed; } // Booleans Boolean CPrefs::SetBoolean(Boolean b, PrefEnum id) { Boolean changed = FALSE; if ( IsNewPrefFormat(id) ) { changed = PREF_SetBoolPref( prefLoc[id].prefName, b ); } PostInitializePref(id, changed); return changed; } // Longs Boolean CPrefs::SetLong(Int32 value, PrefEnum id) { Boolean changed = FALSE; switch(id) // Constrain the values { case Connections: ConstrainTo( CONNECTIONS_MIN, CONNECTIONS_MAX, value ); break; case BufferSize: ConstrainTo( BUFFER_MIN, BUFFER_MAX, value ); break; case DiskCacheSize: unsigned long maxSize; FSSpec diskCacheSpec; diskCacheSpec = GetFolderSpec(DiskCacheFolder ); maxSize = GetFreeSpaceInBytes( diskCacheSpec.vRefNum ) / DISK_CACHE_SCALE; ConstrainTo( DISK_CACHE_MIN, maxSize, value ); break; case DaysTilExpire: if (value!= -1) ConstrainTo( EXPIRE_MIN, EXPIRE_MAX, value ); break; case PrintFlags: ConstrainTo( PRINT_CROPPED, PRINT_RESIZED, value ); break; case NewsArticlesMax: ConstrainTo( NEWS_ARTICLES_MIN, NEWS_ARTICLES_MAX, value ); break; case CheckDocuments: ConstrainTo( (long)CU_CHECK_PER_SESSION, (long)CU_NEVER_CHECK,value ); break; case BackgroundColors: break; case MessageFontStyle: ConstrainTo(MSG_PlainFont, MSG_BoldItalicFont, value); break; case MessageFontSize: ConstrainTo(MSG_NormalSize, MSG_Smaller, value); break; case ProxyConfig: ConstrainTo(PROXY_STYLE_MANUAL, PROXY_STYLE_NONE, value); break; case StartupAsWhat: ConstrainTo(STARTUP_BROWSER, STARTUP_VISIBLE, value); break; case BiffTimeout: ConstrainTo(1, 1200, value); break; case AskMozPassword: ConstrainTo(-1, 1, value); // See secnav.h, SECNAV_SetPasswordPrefs break; #ifdef MOZ_MAILNEWS case SortMailBy: case SortNewsBy: ConstrainTo(MAIL_SORT_BY_DATE, MAIL_SORT_BY_SENDER, value); // See secnav.h, SECNAV_SetPasswordPrefs break; #endif default: break; } if ( IsNewPrefFormat(id) ) { changed = PREF_SetIntPref( prefLoc[id].prefName, value ); } PostInitializePref(id, changed); return changed; } // RGB color Boolean CPrefs::SetColor(const RGBColor& newColor, PrefEnum id) { Boolean changed = FALSE; if ( IsNewPrefFormat(id) ) { changed = PREF_SetColorPref( prefLoc[id].prefName, newColor.red >> 8, newColor.green >> 8, newColor.blue >> 8 ); } else { if ((sColors[id - FIRSTCOLOR].red != newColor.red) || (sColors[id - FIRSTCOLOR].green != newColor.green) || (sColors[id - FIRSTCOLOR].blue != newColor.blue)) changed = TRUE; sColors[id - FIRSTCOLOR] = newColor; } PostInitializePref(id, changed); return changed; } extern const char* CacheFilePrefix; Boolean CPrefs::SetFolderSpec( const FSSpec& newSpec , PrefEnum id ) { Boolean changed; FSSpec oldSpec = sFileIDs[id - FIRSTFOLDER]->GetFolderSpec(); CStr63 oldName( oldSpec.name ); CStr63 newName( newSpec.name ); changed = !( oldSpec.vRefNum == newSpec.vRefNum ) && ( oldSpec.parID == newSpec.parID ) && ( newName == oldName ); if (changed) if ((id == DiskCacheFolder) && !sReading) { NET_SetDiskCacheSize( 0 ); // A hack to clean up the old cache directory NET_CleanupCacheDirectory( "", CacheFilePrefix ); NET_SetDiskCacheSize( CPrefs::DiskCacheSize ); } sFileIDs[id - FIRSTFOLDER]->SetFolderSpec(newSpec, id); PostInitializePref(id, changed); return changed; } // Called from mdmac.c to find the Java component folder OSErr FindGutsFolder(FSSpec* outSpec) { *outSpec = CPrefs::GetFolderSpec(CPrefs::RequiredGutsFolder); return noErr; } // Called from mdmac.c to find the Java component folder OSErr FindNetscapeFolder(FSSpec* outSpec) { *outSpec = CPrefs::GetFolderSpec(CPrefs::NetscapeFolder); return noErr; } // Called from mdmac.c to find the Java component folder OSErr FindJavaDownloadsFolder(FSSpec* outSpec) { *outSpec = CPrefs::GetFilePrototype(CPrefs::NetscapeFolder); CStr255 downName; ::GetIndString( downName, 14000, 5 ); #ifdef DEBUG if (downName.Length() < 4 ) XP_ASSERT(false); // Someone blew away our string #endif LString::CopyPStr( downName, outSpec->name, 32 ); return noErr; } // Called from mkhelp.c to get the standard location of the NetHelp folder as a URL char * FE_GetNetHelpDir() { FSSpec nethelpFolder = CPrefs::GetFolderSpec(CPrefs::NetHelpFolder); return CFileMgr::GetURLFromFileSpec(nethelpFolder); } Boolean CPrefs::GetBoolean(PrefEnum id) { if ( IsNewPrefFormat(id) ) { XP_Bool value; PREF_GetBoolPref( prefLoc[id].prefName, &value ); return value; } else return false; } Int32 CPrefs::GetLong(PrefEnum id) { if ( IsNewPrefFormat(id) ) { int32 value; PREF_GetIntPref( prefLoc[id].prefName, &value ); return (Int32) value; } else return 0; } char * CPrefs::GetStaticString() { static char cStrings[kStaticStrCount][kStaticStrLen]; static short currentCString = 0; currentCString = (currentCString + 1) % kStaticStrCount; char* strbuffer = cStrings[currentCString]; return (strbuffer); } CStr255 CPrefs::GetString(PrefEnum id) { // --xp prefs Note: // Be aware of performance impact here. For some frequently // accessed prefs, we might want to cache value locally // (e.g. HomePage is queried every time menu/toolbar is updated). if ( IsNewPrefFormat(id) ) { int len = kStaticStrLen; char * value = GetStaticString(); // special case to handle "one-time homepage". If a homepage // override is requested and the user hasn't seen it yet, // load the override page instead. if (id == HomePage) { XP_Bool override = false; PREF_GetBoolPref("browser.startup.homepage_override", &override); if (override) { char* url = NULL; PREF_CopyConfigString("startup.homepage_override_url", &url); PREF_SetBoolPref("browser.startup.homepage_override", false); if (url && *url) { strncpy(value, url, len); XP_FREE(url); return value; } } } PREF_GetCharPref( prefLoc[id].prefName, value, &len ); return value; } else return CStr255::sEmptyString; } char* CPrefs::GetCharPtr( PrefEnum id ) { if ( IsNewPrefFormat(id) ) { char* strbuffer = GetStaticString(); int len = kStaticStrLen; PREF_GetCharPref( prefLoc[id].prefName, strbuffer, &len ); return strbuffer; } else return CStr255::sEmptyString; } // --ML no longer inline const RGBColor& CPrefs::GetColor( PrefEnum id ) { if ( IsNewPrefFormat(id) ) { uint8 r, g, b; PREF_GetColorPref( prefLoc[id].prefName, &r, &g, &b ); static RGBColor color; color.red = r << 8; color.green = g << 8; color.blue = b << 8; return color; } return sColors[ id - FIRSTCOLOR ]; } FSSpec CPrefs::GetFolderSpec( PrefEnum id ) { Assert_(sFileIDs[id - FIRSTFILESPEC]); if (sFileIDs[id - FIRSTFILESPEC] == NULL) { FSSpec dummy; dummy.vRefNum = dummy.parID = 0; return dummy; } else return sFileIDs[id - FIRSTFILESPEC]->GetFolderSpec(); } FSSpec CPrefs::GetFilePrototype(PrefEnum id) { // Assert_((id >= FIRSTFILESPEC) && (id <= LastFolder)); Assert_(sFileIDs[id - FIRSTFILESPEC]); if (sFileIDs[id - FIRSTFILESPEC] == NULL) { FSSpec dummy; dummy.vRefNum = dummy.parID = 0; return dummy; } else return sFileIDs[id - FIRSTFILESPEC]->GetFilePrototype(); } char * CPrefs::GetCachePath() { if (sCachePath == NULL) { FSSpec cacheFolder = GetFilePrototype( DiskCacheFolder ); sCachePath = CFileMgr::PathNameFromFSSpec(cacheFolder, FALSE); } return sCachePath; } THPrint CPrefs::GetPrintRecord() { /* If we have already loaded a print record, whatever its origin, use that. If not, create the default one. Note that the standard "get our print record" code already loads the default one, if necessary. Checking again right here is useful only for dynamically detecting when a printer has recently been chosen on a machine for which no printer has ever before been chosen. (It was a bug; don't hunt me down for this one.) */ if (!sPrintRec) try { sPrintRec = UPrintingMgr::GetDefaultPrintRecord(); } catch(...) { } return sPrintRec; } // --Admin Kit support. Animation file must live in Essential Files // or the user's profile folder. void CPrefs::OpenAnimationFile(FSSpec& preferredAnim, FSSpec& secondaryAnim) { char* animFileName; if ( PREF_CopyConfigString("mac_animation_file", &animFileName) == PREF_NOERROR ) { Try_ { LFile* animFile = nil; LString::CopyPStr( (CStr32) animFileName, preferredAnim.name, 32 ); if (CFileMgr::FileExists(preferredAnim)) { animFile = new LFile(preferredAnim); } else { LString::CopyPStr( (CStr32) animFileName, secondaryAnim.name, 32 ); if (CFileMgr::FileExists(secondaryAnim)) { animFile = new LFile(secondaryAnim); } } XP_FREE(animFileName); if (animFile) { animFile->OpenResourceFork(fsRdPerm); CSpinningN::AnimResFile() = animFile->GetResourceForkRefNum(); MoveResourceMapBelowApp(); } } Catch_(inErr) { // file not found or something. Just ignore it. } } } Boolean CPrefs::HasCoBrand() { // Show co-brand if using a custom animation file // (No longer true: or logo URL is changed.) return ( CSpinningN::AnimResFile() != refNum_Undefined ); /* || ( PREF_CopyConfigString("toolbar.logo.url", nil) == PREF_NOERROR );*/ } Boolean CPrefs::IsLocked(PrefEnum id) { if ( IsNewPrefFormat(id) ) { return (Boolean) PREF_PrefIsLocked( prefLoc[id].prefName ); } else { return false; } } char* CPrefs::Concat(const char* base, const char* suffix) { const size_t kBufLength = 256; static char buf[kBufLength]; size_t blen = strlen(base); size_t slen = strlen(suffix); Assert_(blen+slen < kBufLength); memcpy(buf, base, blen); memcpy(&buf[blen], suffix, slen); buf[blen + slen] = '\0'; return buf; } #ifdef MOZ_MAIL_NEWS //---------------------------------------------------------------------------------------- static void HandlePOPPassword() // I moved some common code here. It's static because I don't want to change the header // just for this function, which is entirely of local interest. It's called from two // cases in PostInitializePref below. - 98/02/23 jrm //---------------------------------------------------------------------------------------- { if ( CPrefs::GetBoolean( CPrefs::RememberMailPassword )) NET_SetPopPassword( CPrefs::GetCharPtr( CPrefs::MailPassword) ); else NET_SetPopPassword(NULL); } #endif //---------------------------------------------------------------------------------------- void CPrefs::PostInitializePref(PrefEnum id, Boolean changed) //---------------------------------------------------------------------------------------- { if (changed && !sReading) { sDirty = TRUE; if (gPrefBroadcaster != NULL) gPrefBroadcaster->BroadcastMessage(msg_PrefsChanged, &id); } switch(id) { // Booleans case ThreadMail: case ThreadNews: case ShowToolbar: case DelayImages: case ShowStatus: case ShowURL: case DisplayWhileLoading: break; case MailUseFixedWidthFont: break; case LeaveMailOnServer: break; case MailCCSelf: break; case NewsCCSelf: break; case UseFancyNews: case ShowAllNews: break; case AnchorUnderline: case UseFancyFTP: case LoadHomePage: case ExpireNever: case CustomLinkColors: case ShowDirectory: case AgreedToLicense: case EnteringSecure: case LeavingSecure: case ViewingMixed: case SubmittingInsecure: case ShowSecurity: case CustomVisitedColors: case CustomTextColors: case DefaultMailDelivery: case EnableActiveScrolling: #ifdef EDITOR case EditorUseCustomColors: case EditorUseBackgroundImage: case PublishMaintainLinks: case PublishKeepImages: case ShowCopyright: case ShowFileEditToolbar: case ShowCharacterToolbar: case ShowParagraphToolbar: #endif break; case UseDocumentColors: LO_SetUserOverride(!GetBoolean(id)); break; case UseSigFile: break; case AutoDetectEncoding: case StrictlyMIME: #ifdef MOZ_MAIL_NEWS MIME_ConformToStandard(GetBoolean(id)); #endif // MOZ_MAIL_NEWS break; case UseUtilityBackground: break; case UseInlineViewSource: break; case ShowToolTips: CToolTipAttachment::Enable(GetBoolean(ShowToolTips)); break; case UseInternetConfig: break; case EnableJava: #if defined (JAVA) LJ_SetJavaEnabled( (PRBool)CPrefs::GetBoolean( CPrefs::EnableJava ) ); #endif /* defined (JAVA) */ break; // Longs case LicenseVersion: case TopLeftHeader: case TopMidHeader: case TopRightHeader: case BottomLeftFooter: case BottomMidFooter: case BottomRightFooter: case PrintBackground: case StartupAsWhat: case StartupBitfield: case SortMailBy: case SortNewsBy: case NewsPaneConfig: case MailPaneConfig: case Ciphers: case MailHeaderDisplay: case NewsHeaderDisplay: case AutoSaveTimeDelay: // NOPs break; case DaysTilExpire: if (GetLong(id) != -1) GH_SetGlobalHistoryTimeout( SECONDS_PER_DAY * GetLong(id) ); else GH_SetGlobalHistoryTimeout( -1 ); break; case Connections: NET_ChangeMaxNumberOfConnectionsPerContext(GetLong(id)); break; case BufferSize: NET_ChangeSocketBufferSize( GetLong(id) ); break; case PrintFlags: case NewsArticlesMax: #ifdef MOZ_MAIL_NEWS NET_SetNumberOfNewsArticlesInListing(GetLong(id)); #endif break; case CheckDocuments: NET_SetCacheUseMethod( (CacheUseEnum)GetLong(id) ); break; case FileSortMethod: case ToolbarStyle: case DefaultCharSetID: case DefaultFontEncoding: break; case BackgroundColors: LO_Color loColor; loColor = MakeLOColor(GetColor(TextBkgnd )); LO_SetDefaultColor( LO_COLOR_BG, loColor.red, loColor.green, loColor.blue); break; case MessageFontStyle: case MessageFontSize: break; // Strings case AcceptLanguage: break; case HomePage: break; case NewsHost: #ifdef MOZ_MAIL_NEWS NET_SetNewsHost( GetCharPtr(id) ); #endif break; case UserName: break; case UserEmail: break; case SMTPHost: #if defined(MOZ_MAIL_COMPOSE) || defined(MOZ_MAIL_NEWS) NET_SetMailRelayHost( GetCharPtr(id)); #endif // MOZ_MAIL_COMPOSE || MOZ_MAIL_NEWS break; case SOCKSHost: case SOCKSPort: CStr31 numstr; ::NumToString(GetLong(SOCKSPort), numstr); NET_SetSocksHost(BuildProxyString(GetString(SOCKSHost), numstr)); break; case Organization: // Should we reset mail window here too? break; case PopHost: #ifdef MOZ_MAIL_NEWS HandlePOPPassword(); #endif break; case DefaultMailCC: break; case DefaultNewsCC: break; case ReplyTo: break; case PopID: #ifdef MOZ_MAIL_NEWS NET_SetPopUsername(GetCharPtr(PopID)); #endif break; case AcceptCookies: break; case UseEmailAsPassword: NET_SendEmailAddressAsFTPPassword( CPrefs::GetBoolean( CPrefs::UseEmailAsPassword ) ); break; case SubmitFormsByEmail: NET_WarnOnMailtoPost( CPrefs::GetBoolean( CPrefs::SubmitFormsByEmail ) ? PR_TRUE : PR_FALSE ); break; case DefaultPersonalCertificate: break; // Folders case DownloadFolder: case NetscapeFolder: case MainFolder: case SignatureFile: case HTMLEditor: case ImageEditor: break; case DiskCacheFolder: if (sCachePath) free(sCachePath); sCachePath = NULL; break; case GIFBackdropFile: break; case MailFolder: break; case NewsFolder: break; case SecurityFolder: break; // Colors case TextFore: loColor = MakeLOColor(GetColor(TextFore )); LO_SetDefaultColor( LO_COLOR_FG , loColor.red, loColor.green, loColor.blue); break; case TextBkgnd: loColor = MakeLOColor(GetColor(TextBkgnd )); LO_SetDefaultColor( LO_COLOR_BG, loColor.red, loColor.green, loColor.blue); break; case Anchor: loColor = MakeLOColor(GetColor(Anchor )); LO_SetDefaultColor( LO_COLOR_LINK, loColor.red, loColor.green, loColor.blue); break; case Visited: loColor = MakeLOColor(GetColor(Visited )); LO_SetDefaultColor( LO_COLOR_VLINK, loColor.red, loColor.green, loColor.blue); break; case WindowBkgnd: case EditorText: case EditorLink: case EditorActiveLink: case EditorFollowedLink: case EditorBackground: break; // Print record case PrintRecord: break; case LimitMessageSize: case MaxMessageSize: break; case UseMozPassword: case AskMozPassword: case AskMozPassFrequency: break; #ifdef FORTEZZA case FortezzaTimeoutOn: case FortezzaTimeout: if (!GetBoolean(FortezzaTimeoutOn)) FortezzaSetTimeout(0); else { int timeout = GetLong(FortezzaTimeout); if (timeout <= 0) timeout = 1; FortezzaSetTimeout(timeout); } break; #endif case BiffOn: case BiffTimeout: case AutoQuoteOnReply: break; case MailPassword: #ifdef MOZ_MAIL_NEWS NET_SetPopPassword( GetCharPtr( MailPassword) ); #endif break; case RememberMailPassword: #ifdef MOZ_MAIL_NEWS HandlePOPPassword(); #endif break; default: // Assert_(FALSE); break; } } void CPrefs::Read1MimeTypes() { // If the Prefs file is 3.0-format read it first CMimeMapper* newMap; if ( sPrefFileVersion == 3 && sReading && UsePreferencesResFile() ) { #define DYNAMIC_MIME_RES_TYPE 'MIME' #define STATIC_MIME_RES_TYPE 'SMIM' short howMany = ::Count1Resources( DYNAMIC_MIME_RES_TYPE ); // ¥ handle the case of "first launch" so that we can read all // of the MIME types out of the application's resource fork // (and then write them out to prefs when we quit, so that // next time we launch, they'll be in prefs) short i; Handle res; for ( i = 0; i < howMany; i++ ) { res = ::Get1Resource( DYNAMIC_MIME_RES_TYPE, MIME_PREFS_FIRST_RESID + i ); if ( res && *res ) { newMap = CMimeMapper::CreateMapperForRes(res); sMimeTypes.InsertItemsAt( 1, LArray::index_Last, &newMap ); } } howMany = ::Count1Resources( STATIC_MIME_RES_TYPE ); for ( i = 0; i < howMany; i++ ) { res = ::GetResource( STATIC_MIME_RES_TYPE, i + 1 ); if ( res && *res ) { newMap = CMimeMapper::CreateMapperForRes(res); sMimeTypes.InsertItemsAt( 1, LArray::index_Last, &newMap ); } } } // Always read xp mime default & user prefs char* children; if ( PREF_CreateChildList("mime", &children) == 0 ) { int index = 0; while (char* child = PREF_NextChild(children, &index)) { newMap = CMimeMapper::CreateMapperFor(child, sPrefFileVersion == 4); if (newMap) sMimeTypes.InsertItemsAt( 1, LArray::index_Last, &newMap ); } XP_FREE(children); } } // Try reading in from the preferences file // If it does not work, use the app file void CPrefs::ReadMimeTypes() { Try_ { Read1MimeTypes(); } Catch_(inErr) { } EndCatch_ } // Creates a mapper for an unknown type, and adds it to the list. Returns NULL on failure CMimeMapper* CPrefs::CreateDefaultUnknownMapper(const CStr255& mimeType, Boolean doInsert) { CStr255 appName; ::GetIndString( appName, 300, unknownAppName ); CMimeMapper * newMapper = new CMimeMapper(CMimeMapper::Unknown, mimeType, appName, CStr255::sEmptyString, '????', 'TEXT'); if (newMapper != NULL && doInsert) { sMimeTypes.InsertItemsAt( 1, LArray::index_Last, &newMapper); sDirty = TRUE; newMapper->WriteMimePrefs(); } return newMapper; } // Like CreateDefaultUnknownMapper, except that it uses the application SIG CMimeMapper* CPrefs::CreateDefaultAppMapper(FSSpec &fileSpec,const char * mimeType, Boolean doInsert) { FInfo finderInfo; OSErr err = FSpGetFInfo(&fileSpec, &finderInfo ); CMimeMapper * newMapper = new CMimeMapper(CMimeMapper::Launch, CStr255(mimeType), CStr255(fileSpec.name), CStr255::sEmptyString, finderInfo.fdCreator, // Signature 'TEXT'); // File type if (newMapper != NULL && doInsert) { sMimeTypes.InsertItemsAt( 1, LArray::index_Last, &newMapper); sDirty = TRUE; newMapper->WriteMimePrefs(); } return newMapper; } void CPrefs::SubscribeToPrefChanges( LListener *listener ) { if (gPrefBroadcaster == NULL) gPrefBroadcaster = new LBroadcaster; if (gPrefBroadcaster != NULL) gPrefBroadcaster->AddListener(listener); } void CPrefs::UnsubscribeToPrefChanges( LListener *listener ) { if (gPrefBroadcaster != NULL) gPrefBroadcaster->RemoveListener(listener); } void FE_RememberPopPassword(MWContext*, const char * password) { #ifdef MOZ_MAIL_NEWS // if we aren't supposed to remember clear anything in the registry XP_Bool prefBool; XP_Bool passwordProtectLocalCache; PREF_GetBoolPref("mail.remember_password",&prefBool); PREF_GetBoolPref("mail.password_protect_local_cache", &passwordProtectLocalCache); if (prefBool || passwordProtectLocalCache) PREF_SetCharPref("mail.pop_password",(char *)password); else PREF_SetCharPref("mail.pop_password",""); #else CPrefs::SetString( password, CPrefs::MailPassword ); #endif // MOZ_MAIL_NEWS }