зеркало из https://github.com/mozilla/pjs.git
Landing semi-single-profile on the trunk (merge from the AVIARY_1_0_20040515_BRANCH).
This commit is contained in:
Родитель
1d3271fb25
Коммит
4fb772d656
|
@ -0,0 +1,37 @@
|
|||
#
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
|
||||
DEPTH = ../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
DIRS = public src
|
||||
|
||||
# Use Qute for non-Phoenix apps
|
||||
ifndef MOZ_PHOENIX
|
||||
DIRS += skin
|
||||
endif
|
||||
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
|
@ -0,0 +1,224 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code, released
|
||||
* March 31, 1998.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998-1999 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Ben Goodger (30/09/99)
|
||||
* Brant Gurganus (23/03/03)
|
||||
* Stefan Borggraefe (17/10/03)
|
||||
* Benjamin Smedberg <bsmedberg@covad.net> - 8-Apr-2004
|
||||
*/
|
||||
|
||||
const C = Components.classes;
|
||||
const I = Components.interfaces;
|
||||
|
||||
const ToolkitProfileService = "@mozilla.org/toolkit/profile-service;1";
|
||||
|
||||
var gProfileService;
|
||||
var gProfileManagerBundle;
|
||||
|
||||
var gDefaultProfileParent;
|
||||
var gOldProfileName;
|
||||
|
||||
// The directory where the profile will be created.
|
||||
var gProfileRoot;
|
||||
|
||||
// Text node to display the location and name of the profile to create.
|
||||
var gProfileDisplay;
|
||||
|
||||
// Called once when the wizard is opened.
|
||||
function initWizard()
|
||||
{
|
||||
try {
|
||||
gProfileService = C[ToolkitProfileService].getService(I.nsIToolkitProfileService);
|
||||
gProfileManagerBundle = document.getElementById("bundle_profileManager");
|
||||
|
||||
var dirService = C["@mozilla.org/file/directory_service;1"].getService(I.nsIProperties);
|
||||
gDefaultProfileParent = dirService.get("DefProfRt", I.nsIFile);
|
||||
|
||||
gOldProfileName = document.getElementById("profileName").value;
|
||||
|
||||
// Initialize the profile location display.
|
||||
gProfileDisplay = document.getElementById("profileDisplay").firstChild;
|
||||
setDisplayToDefaultFolder();
|
||||
}
|
||||
catch(e) {
|
||||
window.close();
|
||||
throw (e);
|
||||
}
|
||||
}
|
||||
|
||||
// Called every time the second wizard page is displayed.
|
||||
function initSecondWizardPage()
|
||||
{
|
||||
var profileName = document.getElementById("profileName");
|
||||
profileName.select();
|
||||
profileName.focus();
|
||||
|
||||
// Initialize profile name validation.
|
||||
checkCurrentInput(profileName.value);
|
||||
}
|
||||
|
||||
function setDisplayToDefaultFolder()
|
||||
{
|
||||
var defaultProfileDir = gDefaultProfileParent.clone();
|
||||
defaultProfileDir.append(document.getElementById("profileName").value);
|
||||
gProfileRoot = defaultProfileDir;
|
||||
document.getElementById("useDefault").disabled = true;
|
||||
}
|
||||
|
||||
function updateProfileDisplay()
|
||||
{
|
||||
gProfileDisplay.data = gProfileRoot.path;
|
||||
}
|
||||
|
||||
// Invoke a folder selection dialog for choosing the directory of profile storage.
|
||||
function chooseProfileFolder()
|
||||
{
|
||||
var newProfileRoot;
|
||||
|
||||
var dirChooser = C["@mozilla.org/filepicker;1"].createInstance(I.nsIFilePicker);
|
||||
dirChooser.init(window, gProfileManagerBundle.getString("chooseFolder"),
|
||||
I.nsIFilePicker.modeGetFolder);
|
||||
dirChooser.appendFilters(I.nsIFilePicker.filterAll);
|
||||
dirChooser.show();
|
||||
newProfileRoot = dirChooser.file;
|
||||
|
||||
// Disable the "Default Folder..." button when the default profile folder
|
||||
// was selected manually in the File Picker.
|
||||
// This is always false on Windows, until bug 221872 is fixed.
|
||||
document.getElementById("useDefault").disabled =
|
||||
(newProfileRoot.parent.equals(gDefaultProfileParent));
|
||||
|
||||
gProfileRoot = newProfileRoot;
|
||||
updateProfileDisplay();
|
||||
}
|
||||
|
||||
// Checks the current user input for validity and triggers an error message accordingly.
|
||||
function checkCurrentInput(currentInput)
|
||||
{
|
||||
var finishButton = document.documentElement.getButton("finish");
|
||||
var finishText = document.getElementById("finishText");
|
||||
var canAdvance;
|
||||
|
||||
var errorMessage = checkProfileName(currentInput);
|
||||
|
||||
if (!errorMessage) {
|
||||
finishText.className = "";
|
||||
finishText.firstChild.data = gProfileManagerBundle.getString("profileFinishText");
|
||||
canAdvance = true;
|
||||
}
|
||||
else {
|
||||
finishText.className = "error";
|
||||
finishText.firstChild.data = errorMessage;
|
||||
canAdvance = false;
|
||||
}
|
||||
|
||||
document.documentElement.canAdvance = canAdvance;
|
||||
finishButton.disabled = !canAdvance;
|
||||
|
||||
updateProfileDisplay();
|
||||
}
|
||||
|
||||
function updateProfileName(aNewName) {
|
||||
checkCurrentInput(aNewName);
|
||||
|
||||
if (gProfileRoot.leafName == gOldProfileName) {
|
||||
gProfileRoot.leafName = aNewName;
|
||||
updateProfileDisplay();
|
||||
}
|
||||
gOldProfileName = aNewName;
|
||||
}
|
||||
|
||||
// Checks whether the given string is a valid profile name.
|
||||
// Returns an error message describing the error in the name or "" when it's valid.
|
||||
function checkProfileName(profileNameToCheck)
|
||||
{
|
||||
// Check for emtpy profile name.
|
||||
if (!/\S/.test(profileNameToCheck))
|
||||
return gProfileManagerBundle.getString("profileNameEmpty");
|
||||
|
||||
// Check whether all characters in the profile name are allowed.
|
||||
if (/([\\*:?<>|\/\"])/.test(profileNameToCheck))
|
||||
return gProfileManagerBundle.getFormattedString("invalidChar", [RegExp.$1]);
|
||||
|
||||
// Check whether a profile with the same name already exists.
|
||||
if (profileExists(profileNameToCheck))
|
||||
return gProfileManagerBundle.getString("profileExists");
|
||||
|
||||
// profileNameToCheck is valid.
|
||||
return "";
|
||||
}
|
||||
|
||||
function profileExists(aName)
|
||||
{
|
||||
var profiles = gProfileService.profiles;
|
||||
while (profiles.hasMoreElements()) {
|
||||
var profile = profiles.getNext().QueryInterface(I.nsIToolkitProfile);
|
||||
if (profile.name.toLowerCase() == aName.toLowerCase())
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Called when the first wizard page is shown.
|
||||
function enableNextButton()
|
||||
{
|
||||
document.documentElement.canAdvance = true;
|
||||
}
|
||||
|
||||
function onFinish()
|
||||
{
|
||||
var profileName = document.getElementById("profileName").value;
|
||||
var profile;
|
||||
|
||||
// Create profile named profileName in profileRoot.
|
||||
try {
|
||||
profile = gProfileService.createProfile(gProfileRoot, profileName);
|
||||
}
|
||||
catch (e) {
|
||||
var profileCreationFailed =
|
||||
gProfileManagerBundle.getString("profileCreationFailed");
|
||||
var profileCreationFailedTitle =
|
||||
gProfileManagerBundle.getString("profileCreationFailedTitle");
|
||||
var promptService = C["@mozilla.org/embedcomp/prompt-service;1"].
|
||||
getService(I.nsIPromptService);
|
||||
promptService.alert(window, profileCreationFailedTitle,
|
||||
profileCreationFailed + "\n" + e);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// window.opener is false if the Create Profile Wizard was opened from the
|
||||
// command line.
|
||||
if (window.opener) {
|
||||
// Add new profile to the list in the Profile Manager.
|
||||
window.opener.CreateProfile(profile);
|
||||
}
|
||||
else {
|
||||
// Use the newly created Profile.
|
||||
var profileLock = profile.lock();
|
||||
|
||||
var dialogParams = window.arguments[0].QueryInterface(I.nsIDialogParamBlock);
|
||||
dialogParams.objects.insertElementAt(profileLock, 0, false);
|
||||
}
|
||||
|
||||
// Exit the wizard.
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
|
||||
|
||||
<!DOCTYPE wizard [
|
||||
<!ENTITY % brandDTD SYSTEM "chrome://global/locale/brand.dtd">
|
||||
%brandDTD;
|
||||
<!ENTITY % profileDTD SYSTEM "chrome://mozapps/locale/profile/createProfileWizard.dtd">
|
||||
%profileDTD;
|
||||
]>
|
||||
|
||||
<wizard id="createProfileWizard"
|
||||
title="&newprofile.title;"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onwizardfinish="return onFinish();"
|
||||
onload="initWizard();"
|
||||
style="&window.size;">
|
||||
|
||||
<stringbundle id="bundle_profileManager"
|
||||
src="chrome://mozapps/locale/profile/profileSelection.properties"/>
|
||||
|
||||
<script type="application/x-javascript"
|
||||
src="chrome://mozapps/content/profile/createProfileWizard.js"/>
|
||||
|
||||
<wizardpage id="explanation" onpageshow="enableNextButton();">
|
||||
<description>&profileCreationExplanation_1.text;</description>
|
||||
<description>&profileCreationExplanation_2.text;</description>
|
||||
<description>&profileCreationExplanation_3.text;</description>
|
||||
<spacer flex="1"/>
|
||||
<description>&profileCreationExplanation_4.text;</description>
|
||||
</wizardpage>
|
||||
|
||||
<wizardpage id="createProfile" onpageshow="initSecondWizardPage();">
|
||||
<description>&profileCreationIntro.text;</description>
|
||||
|
||||
<label accesskey="&profilePrompt.accesskey;" control="ProfileName">&profilePrompt.label;</label>
|
||||
<textbox id="profileName" value="&profileDefaultName;"
|
||||
oninput="updateProfileName(this.value);"/>
|
||||
|
||||
<separator/>
|
||||
|
||||
<description>&profileDirExplanation.text;</description>
|
||||
|
||||
<vbox class="indent" flex="1" style="overflow: auto;">
|
||||
<description id="profileDisplay">*</description>
|
||||
</vbox>
|
||||
|
||||
<hbox>
|
||||
<button label="&button.choosefolder.label;" oncommand="chooseProfileFolder();"
|
||||
accesskey="&button.choosefolder.accesskey;"/>
|
||||
|
||||
<button id="useDefault" label="&button.usedefault.label;"
|
||||
oncommand="setDisplayToDefaultFolder(); updateProfileDisplay();"
|
||||
accesskey="&button.usedefault.accesskey;" disabled="true"/>
|
||||
</hbox>
|
||||
|
||||
<separator/>
|
||||
|
||||
<description id="finishText">*</description>
|
||||
</wizardpage>
|
||||
|
||||
</wizard>
|
|
@ -0,0 +1,257 @@
|
|||
/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code, released
|
||||
* March 31, 1998.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998-1999 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Ben Goodger (03/01/00)
|
||||
* Seth Spitzer (28/10/99)
|
||||
* Dan Veditz <dveditz@netscape.com>
|
||||
* Benjamin Smedberg <bsmedberg@covad.net>
|
||||
*/
|
||||
|
||||
const C = Components.classes;
|
||||
const I = Components.interfaces;
|
||||
|
||||
const ToolkitProfileService = "@mozilla.org/toolkit/profile-service;1";
|
||||
const PromptService = "@mozilla.org/embedcomp/prompt-service;1";
|
||||
|
||||
var gDialogParams;
|
||||
var gProfileManagerBundle;
|
||||
var gBrandBundle;
|
||||
var gProfileService;
|
||||
var gPromptService;
|
||||
|
||||
function startup()
|
||||
{
|
||||
try {
|
||||
gDialogParams = window.arguments[0].
|
||||
QueryInterface(I.nsIDialogParamBlock);
|
||||
|
||||
gProfileService = C[ToolkitProfileService].getService(I.nsIToolkitProfileService);
|
||||
|
||||
gProfileManagerBundle = document.getElementById("bundle_profileManager");
|
||||
gBrandBundle = document.getElementById("bundle_brand");
|
||||
|
||||
gPromptService = C[PromptService].getService(I.nsIPromptService);
|
||||
|
||||
document.documentElement.centerWindowOnScreen();
|
||||
|
||||
var profilesElement = document.getElementById("profiles");
|
||||
|
||||
var profileList = gProfileService.profiles;
|
||||
while (profileList.hasMoreElements()) {
|
||||
var profile = profileList.getNext().QueryInterface(I.nsIToolkitProfile);
|
||||
|
||||
var listitem = profilesElement.appendItem(profile.name, "");
|
||||
|
||||
var tooltiptext =
|
||||
gProfileManagerBundle.getFormattedString("profileTooltip", [profile.name, profile.rootDir.path]);
|
||||
listitem.setAttribute("tooltiptext", tooltiptext);
|
||||
listitem.setAttribute("class", "listitem-iconic");
|
||||
listitem.profile = profile;
|
||||
try {
|
||||
if (profile === gProfileService.selectedProfile) {
|
||||
profilesElement.selectedItem = listitem;
|
||||
}
|
||||
}
|
||||
catch(e) { }
|
||||
}
|
||||
|
||||
var autoSelectLastProfile = document.getElementById("autoSelectLastProfile");
|
||||
autoSelectLastProfile.checked = gProfileService.startWithLastProfile;
|
||||
profilesElement.focus();
|
||||
}
|
||||
catch(e) {
|
||||
window.close();
|
||||
throw (e);
|
||||
}
|
||||
}
|
||||
|
||||
function acceptDialog()
|
||||
{
|
||||
var appName = gBrandBundle.getString("brandShortName");
|
||||
|
||||
var profilesElement = document.getElementById("profiles");
|
||||
var selectedProfile = profilesElement.selectedItem;
|
||||
if (!selectedProfile) {
|
||||
var pleaseSelectTitle = gProfileManagerBundle.getString("pleaseSelectTitle");
|
||||
var pleaseSelect =
|
||||
gProfileManagerBundle.getFormattedString("pleaseSelect", [appName]);
|
||||
gPromptService.alert(window, pleaseSelectTitle, pleaseSelect);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
var profileLock;
|
||||
|
||||
try {
|
||||
profileLock = selectedProfile.profile.lock();
|
||||
}
|
||||
catch (e) {
|
||||
var lockedTitle = gProfileManagerBundle.getString("profileLockedTitle");
|
||||
var locked =
|
||||
gProfileManagerBundle.getFormattedString("profileLocked", [appName, selectedProfile.profile.name]);
|
||||
gPromptService.alert(window, lockedTitle, locked);
|
||||
|
||||
return false;
|
||||
}
|
||||
gDialogParams.objects.insertElementAt(profileLock.nsIProfileLock, 0, false);
|
||||
|
||||
var autoSelectLastProfile = document.getElementById("autoSelectLastProfile");
|
||||
gProfileService.startWithLastProfile = autoSelectLastProfile.checked;
|
||||
gProfileService.selectedProfile = selectedProfile.profile;
|
||||
|
||||
gProfileService.startOffline = document.getElementById("offlineState").checked;
|
||||
|
||||
gDialogParams.SetInt(0, 1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// handle key event on listboxes
|
||||
function onProfilesKey(aEvent)
|
||||
{
|
||||
switch( aEvent.keyCode )
|
||||
{
|
||||
case 46:
|
||||
confirmDelete();
|
||||
break;
|
||||
case "VK_F2":
|
||||
renameProfile();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function onProfilesDblClick(aEvent)
|
||||
{
|
||||
if(aEvent.target.localName == "listitem")
|
||||
document.documentElement.acceptDialog();
|
||||
}
|
||||
|
||||
// invoke the createProfile Wizard
|
||||
function CreateProfileWizard()
|
||||
{
|
||||
window.openDialog('chrome://mozapps/content/profile/createProfileWizard.xul',
|
||||
'', 'centerscreen,chrome,modal,titlebar', gProfileService);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from createProfileWizard to update the display.
|
||||
*/
|
||||
function CreateProfile(aProfile)
|
||||
{
|
||||
var profilesElement = document.getElementById("profiles");
|
||||
|
||||
var listitem = profilesElement.appendItem(aProfile.name, "");
|
||||
|
||||
var tooltiptext =
|
||||
gProfileManagerBundle.getFormattedString("profileTooltip", [aProfile.name, aProfile.rootDir.path]);
|
||||
listitem.setAttribute("tooltiptext", tooltiptext);
|
||||
listitem.setAttribute("class", "listitem-iconic");
|
||||
listitem.profile = aProfile;
|
||||
|
||||
profilesElement.ensureElementIsVisible(listitem);
|
||||
profilesElement.selectItem(listitem);
|
||||
}
|
||||
|
||||
// rename the selected profile
|
||||
function RenameProfile()
|
||||
{
|
||||
var profilesElement = document.getElementById("profiles");
|
||||
var selectedItem = profilesElement.selectedItem;
|
||||
if (!selectedItem) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var selectedProfile = selectedItem.profile;
|
||||
|
||||
var oldName = selectedProfile.name;
|
||||
var newName = {value: oldName};
|
||||
|
||||
var dialogTitle = gProfileManagerBundle.getString("renameProfileTitle");
|
||||
var msg =
|
||||
gProfileManagerBundle.getFormattedString("renameProfilePrompt", [oldName]);
|
||||
|
||||
if (gPromptService.prompt(window, dialogTitle, msg, newName, null, {value:0})) {
|
||||
newName = newName.value;
|
||||
|
||||
// User hasn't changed the profile name. Treat as if cancel was pressed.
|
||||
if (newName == oldName)
|
||||
return false;
|
||||
|
||||
try {
|
||||
selectedProfile.name = newName;
|
||||
}
|
||||
catch (e) {
|
||||
var alTitle = gProfileManagerBundle.getString("profileNameInvalidTitle");
|
||||
var alMsg = gProfileManagerBundle.getFormattedString("profileNameInvalid", [newName]);
|
||||
gPromptService.alert(window, alTitle, alMsg);
|
||||
return false;
|
||||
}
|
||||
|
||||
selectedItem.label = newName;
|
||||
var tooltiptext =
|
||||
gProfileManagerBundle.getFormattedString("profileTooltip", [newName, aProfile.rootDir.path]);
|
||||
listitem.setAttribute("tooltiptext", tooltiptext);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function ConfirmDelete()
|
||||
{
|
||||
var deleteButton = document.getElementById("delbutton");
|
||||
var profileList = document.getElementById( "profiles" );
|
||||
|
||||
var selectedItem = profileList.selectedItem;
|
||||
if (!selectedItem) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var selectedProfile = selectedItem.profile;
|
||||
var deleteFiles = false;
|
||||
|
||||
if (selectedProfile.rootDir.exists()) {
|
||||
var dialogTitle = gProfileManagerBundle.getString("deleteTitle");
|
||||
var dialogText =
|
||||
gProfileManagerBundle.getFormattedString("deleteProfile",
|
||||
[selectedProfile.rootDir.path]);
|
||||
|
||||
var buttonPressed = gPromptService.confirmEx(window, dialogTitle, dialogText,
|
||||
(gPromptService.BUTTON_TITLE_IS_STRING * gPromptService.BUTTON_POS_0) +
|
||||
(gPromptService.BUTTON_TITLE_CANCEL * gPromptService.BUTTON_POS_1) +
|
||||
(gPromptService.BUTTON_TITLE_IS_STRING * gPromptService.BUTTON_POS_2),
|
||||
gProfileManagerBundle.getString("dontDeleteFiles"),
|
||||
null,
|
||||
gProfileManagerBundle.getString("deleteFiles"),
|
||||
null, {value:0});
|
||||
if (buttonPressed == 1)
|
||||
return false;
|
||||
|
||||
if (buttonPressed == 2)
|
||||
deleteFiles = true;
|
||||
}
|
||||
|
||||
selectedProfile.remove(deleteFiles);
|
||||
selectedItem.parentNode.removeChild(selectedItem);
|
||||
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- -*- Mode: SGML; indent-tabs-mode: nil; -*- -->
|
||||
<!--
|
||||
|
||||
The contents of this file are subject to the Netscape Public
|
||||
License Version 1.1 (the "License"); you may not use this file
|
||||
except in compliance with the License. You may obtain a copy of
|
||||
the License at http://www.mozilla.org/NPL/
|
||||
|
||||
Software distributed under the License is distributed on an "AS
|
||||
IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
implied. See the License for the specific language governing
|
||||
rights and limitations under the License.
|
||||
|
||||
The Original Code is mozilla.org code.
|
||||
|
||||
The Initial Developer of the Original Code is Netscape
|
||||
Communications Corporation. Portions created by Netscape are
|
||||
Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
Contributors:
|
||||
Code: Ben Goodger <ben@netscape.com>
|
||||
Benjamin Smedberg <bsmedberg@covad.net>
|
||||
UI Ideas: Matthew Thomas, Ben Gregory
|
||||
|
||||
-->
|
||||
|
||||
<?xml-stylesheet href="chrome://mozapps/skin/profile/profileSelection.css" type="text/css"?>
|
||||
|
||||
<!DOCTYPE window [
|
||||
<!ENTITY % brandDTD SYSTEM "chrome://global/locale/brand.dtd">
|
||||
%brandDTD;
|
||||
<!ENTITY % profileDTD SYSTEM "chrome://mozapps/locale/profile/profileSelection.dtd">
|
||||
%profileDTD;
|
||||
]>
|
||||
|
||||
<dialog
|
||||
id="profileWindow"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
class="non-resizable"
|
||||
title="&windowtitle.label;"
|
||||
orient="vertical"
|
||||
buttons="accept,cancel"
|
||||
style="width: 30em;"
|
||||
onload="startup();"
|
||||
ondialogaccept="return acceptDialog()"
|
||||
buttonlabelaccept="&start.label;"
|
||||
buttonlabelcancel="&exit.label;">
|
||||
|
||||
<stringbundle id="bundle_profileManager"
|
||||
src="chrome://mozapps/locale/profile/profileSelection.properties"/>
|
||||
<stringbundle id="bundle_brand"
|
||||
src="chrome://global/locale/brand.properties"/>
|
||||
|
||||
<script type="application/x-javascript" src="chrome://mozapps/content/profile/profileSelection.js"/>
|
||||
|
||||
<description class="label">&pmDescription.label;</description>
|
||||
|
||||
<separator class="thin"/>
|
||||
|
||||
<hbox class="profile-box indent" flex="1">
|
||||
|
||||
<vbox id="managebuttons">
|
||||
<button id="newbutton" label="&newButton.label;"
|
||||
accesskey="&newButton.accesskey;" oncommand="CreateProfileWizard();"/>
|
||||
<button id="renbutton" label="&renameButton.label;"
|
||||
accesskey="&renameButton.accesskey;" oncommand="RenameProfile();"/>
|
||||
<button id="delbutton" label="&deleteButton.label;"
|
||||
accesskey="&deleteButton.accesskey;" oncommand="ConfirmDelete();"/>
|
||||
</vbox>
|
||||
|
||||
<separator flex="1"/>
|
||||
|
||||
<vbox flex="1">
|
||||
<listbox id="profiles" flex="1" rows="5" seltype="single"
|
||||
ondblclick="onProfilesDblClick(event)"
|
||||
onkeypress="onProfilesKey(event);">
|
||||
</listbox>
|
||||
|
||||
<checkbox id="offlineState" label="&offlineState.label;" accesskey="&offlineState.accesskey;"/>
|
||||
|
||||
<checkbox id="autoSelectLastProfile" label="&autoSelect.label;"
|
||||
accesskey="&autoSelect.accesskey;"/>
|
||||
</vbox>
|
||||
|
||||
</hbox>
|
||||
</dialog>
|
|
@ -0,0 +1,10 @@
|
|||
toolkit.jar:
|
||||
content/mozapps/profile/createProfileWizard.js (content/createProfileWizard.js)
|
||||
content/mozapps/profile/createProfileWizard.xul (content/createProfileWizard.xul)
|
||||
content/mozapps/profile/profileSelection.js (content/profileSelection.js)
|
||||
content/mozapps/profile/profileSelection.xul (content/profileSelection.xul)
|
||||
|
||||
en-US.jar:
|
||||
locale/en-US/mozapps/profile/createProfileWizard.dtd (locale/createProfileWizard.dtd)
|
||||
locale/en-US/mozapps/profile/profileSelection.properties (locale/profileSelection.properties)
|
||||
locale/en-US/mozapps/profile/profileSelection.dtd (locale/profileSelection.dtd)
|
|
@ -0,0 +1,49 @@
|
|||
<!-- -*- Mode: SGML; indent-tabs-mode: nil; -*- -->
|
||||
<!--
|
||||
|
||||
The contents of this file are subject to the Netscape Public
|
||||
License Version 1.1 (the "License"); you may not use this file
|
||||
except in compliance with the License. You may obtain a copy of
|
||||
the License at http://www.mozilla.org/NPL/
|
||||
|
||||
Software distributed under the License is distributed on an "AS
|
||||
IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
implied. See the License for the specific language governing
|
||||
rights and limitations under the License.
|
||||
|
||||
The Original Code is mozilla.org code.
|
||||
|
||||
The Initial Developer of the Original Code is Netscape
|
||||
Communications Corporation. Portions created by Netscape are
|
||||
Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
Contributor(s):
|
||||
Ben Goodger (28/10/99)
|
||||
|
||||
-->
|
||||
|
||||
<!ENTITY windowtitle.label "&brandShortName; - Choose User Profile">
|
||||
|
||||
<!ENTITY profilename.label "Profile Name:">
|
||||
|
||||
<!ENTITY start.label "Start &brandShortName;">
|
||||
<!ENTITY exit.label "Exit">
|
||||
|
||||
<!ENTITY availprofiles.label "Available Profiles">
|
||||
|
||||
<!ENTITY newButton.label "Create Profile...">
|
||||
<!ENTITY newButton.accesskey "C">
|
||||
<!ENTITY renameButton.label "Rename Profile...">
|
||||
<!ENTITY renameButton.accesskey "R">
|
||||
<!ENTITY deleteButton.label "Delete Profile...">
|
||||
<!ENTITY deleteButton.accesskey "D">
|
||||
|
||||
<!-- manager entities -->
|
||||
<!ENTITY pmDescription.label "&brandShortName; stores information about your settings, preferences, and other user items in your user profile.">
|
||||
|
||||
<!ENTITY offlineState.label "Work offline">
|
||||
<!ENTITY offlineState.accesskey "o">
|
||||
|
||||
<!ENTITY autoSelect.label "Don't ask at startup">
|
||||
<!ENTITY autoSelect.accesskey "s">
|
|
@ -0,0 +1,53 @@
|
|||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is Mozilla Seamonkey bootstrap code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Benjamin Smedberg <bsmedberg@covad.net>
|
||||
# Portions created by the Initial Developer are Copyright (C) 2004
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = xulapp
|
||||
XPIDL_MODULE = toolkitprofile
|
||||
|
||||
XPIDLSRCS = \
|
||||
nsIProfileMigrator.idl \
|
||||
nsIToolkitProfile.idl \
|
||||
nsIToolkitProfileService.idl \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
|
@ -0,0 +1,108 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is The Browser Profile Migrator.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Ben Goodger.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2004
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Ben Goodger <ben@bengoodger.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
interface nsIFile;
|
||||
|
||||
/**
|
||||
* Helper interface for nsIProfileMigrator.
|
||||
*
|
||||
* @provider Toolkit (Startup code)
|
||||
* @client Application (Profile-migration code)
|
||||
* @obtainable nsIProfileMigrator.migrate
|
||||
*/
|
||||
[scriptable, uuid(048e5ca1-0eb7-4bb1-a9a2-a36f7d4e0e3c)]
|
||||
interface nsIProfileStartup : nsISupports
|
||||
{
|
||||
/**
|
||||
* The root directory of the semi-current profile, during profile migration.
|
||||
* After nsIProfileMigrator.migrate has returned, this object will not be
|
||||
* useful.
|
||||
*/
|
||||
readonly attribute nsIFile directory;
|
||||
|
||||
/**
|
||||
* Do profile-startup by setting NS_APP_USER_PROFILE_50_DIR in the directory
|
||||
* service and notifying the profile-startup observer topics.
|
||||
*/
|
||||
void doStartup();
|
||||
};
|
||||
|
||||
/**
|
||||
* Migrate application settings from an outside source.
|
||||
*
|
||||
* @provider Application (Profile-migration code)
|
||||
* @client Toolkit (Startup code)
|
||||
* @obtainable service, contractid("@mozilla.org/toolkit/profile-migrator;1")
|
||||
*/
|
||||
[scriptable, uuid(24ce8b9d-b7ff-4279-aef4-26e158f03e34)]
|
||||
interface nsIProfileMigrator : nsISupports
|
||||
{
|
||||
/**
|
||||
* Import existing profile paths. When the app is started the first
|
||||
* time, if there are no INI-style profiles, appstartup will call
|
||||
* this method to import any registry- style profiles that may
|
||||
* exist. When this method is called, there is no event queue
|
||||
* service and this method should not attempt to use the network or
|
||||
* show any GUI.
|
||||
*
|
||||
* @note You don't actually have to move the profile data. Just call
|
||||
* nsIToolkitProfileService.create on the existing profile path(s).
|
||||
*/
|
||||
void import();
|
||||
|
||||
/**
|
||||
* Do profile migration.
|
||||
*
|
||||
* When this method is called, a default profile has been created;
|
||||
* XPCOM has been initialized such that compreg.dat is in the
|
||||
* profile; the directory service does *not* return a key for
|
||||
* NS_APP_USER_PROFILE_50_DIR or any of the keys depending on an active
|
||||
* profile. To figure out the directory of the "current" profile, use
|
||||
* aStartup.directory.
|
||||
*
|
||||
* If your migrator needs to access services that use the profile (to
|
||||
* set profile prefs or bookmarks, for example), use aStartup.doStartup.
|
||||
*
|
||||
* The startup code ignores COM exceptions thrown from this method.
|
||||
*/
|
||||
void migrate(in nsIProfileStartup aStartup);
|
||||
};
|
||||
|
||||
%{C++
|
||||
#define NS_PROFILEMIGRATOR_CONTRACTID "@mozilla.org/toolkit/profile-migrator;1"
|
||||
%}
|
|
@ -0,0 +1,63 @@
|
|||
/* -*- Mode: IDL; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the new Mozilla toolkit.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Benjamin Smedberg <bsmedberg@covad.net>
|
||||
* Portions created by the Initial Developer are Copyright (C) 2004
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsILocalFile;
|
||||
interface nsIToolkitProfile;
|
||||
|
||||
/**
|
||||
* Hold on to a profile lock. Once you release the last reference to this
|
||||
* interface, the profile lock is released.
|
||||
*/
|
||||
[scriptable, uuid(6f987826-e4dd-453d-bb66-a1e46088fced)]
|
||||
interface nsIProfileLock : nsISupports
|
||||
{
|
||||
readonly attribute nsILocalFile directory;
|
||||
|
||||
void unlock();
|
||||
};
|
||||
|
||||
[scriptable, uuid(87cea5c2-b9ed-44f9-8984-e75bc9f7134a)]
|
||||
interface nsIToolkitProfile : nsISupports
|
||||
{
|
||||
readonly attribute nsILocalFile rootDir;
|
||||
attribute AUTF8String name;
|
||||
|
||||
void remove(in boolean removeFiles);
|
||||
nsIProfileLock lock();
|
||||
};
|
|
@ -0,0 +1,93 @@
|
|||
/* -*- Mode: IDL; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the new Mozilla toolkit.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Benjamin Smedberg <bsmedberg@covad.net>
|
||||
* Portions created by the Initial Developer are Copyright (C) 2004
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsISimpleEnumerator;
|
||||
interface nsILocalFile;
|
||||
interface nsIToolkitProfile;
|
||||
interface nsIProfileLock;
|
||||
|
||||
[scriptable, uuid(9b434f48-438c-4f85-89de-b7f321a45341)]
|
||||
interface nsIToolkitProfileService : nsISupports
|
||||
{
|
||||
attribute boolean startWithLastProfile;
|
||||
attribute boolean startOffline;
|
||||
|
||||
readonly attribute nsISimpleEnumerator /*nsIToolkitProfile*/ profiles;
|
||||
|
||||
attribute nsIToolkitProfile selectedProfile;
|
||||
|
||||
/**
|
||||
* Get a profile by name. This is mainly for use by the -P
|
||||
* commandline flag.
|
||||
*
|
||||
* @param aName The profile name to find.
|
||||
*/
|
||||
nsIToolkitProfile getProfileByName(in AUTF8String aName);
|
||||
|
||||
/**
|
||||
* Lock an arbitrary path as a profile. If the path does not exist, it
|
||||
* will be created and the defaults copied from the application directory.
|
||||
*/
|
||||
nsIProfileLock lockProfilePath(in nsILocalFile aDirectory);
|
||||
|
||||
/**
|
||||
* Create a new profile.
|
||||
*
|
||||
* @param rootDir The profile directory. May be null, in which case a suitable
|
||||
* default will be chosen based on the profile name.
|
||||
* @param name The profile name.
|
||||
*/
|
||||
nsIToolkitProfile createProfile(in nsILocalFile rootDir,
|
||||
in AUTF8String name);
|
||||
|
||||
/**
|
||||
* Returns the number of profiles.
|
||||
* @return 0, 1, or 2. More than 2 profiles will always return 2.
|
||||
*/
|
||||
readonly attribute unsigned long profileCount;
|
||||
|
||||
/**
|
||||
* Flush the profiles list file.
|
||||
*/
|
||||
void flush();
|
||||
};
|
||||
|
||||
%{C++
|
||||
#define NS_PROFILESERVICE_CONTRACTID "@mozilla.org/toolkit/profile-service;1"
|
||||
%}
|
|
@ -0,0 +1,29 @@
|
|||
#
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
|
@ -0,0 +1,3 @@
|
|||
classic.jar:
|
||||
skin/classic/mozapps/profile/profileSelection.css
|
||||
skin/classic/mozapps/profile/profileicon.png
|
|
@ -0,0 +1,52 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is new Mozilla XUL toolkit.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Benjamin Smedberg <bsmedberg@covad.net>
|
||||
* Portions created by the Initial Developer are Copyright (C) 2004
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
|
||||
@import url("chrome://global/skin/global.css");
|
||||
|
||||
@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
|
||||
|
||||
#profiles > listitem {
|
||||
list-style-image: url("chrome://mozapps/skin/profile/profileicon.png");
|
||||
}
|
||||
|
||||
box#managebuttons > button {
|
||||
min-width: 8em;
|
||||
}
|
||||
|
||||
#managebuttons {
|
||||
padding-top: 1em;
|
||||
}
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 795 B |
|
@ -0,0 +1,55 @@
|
|||
#
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = xulapp
|
||||
LIBRARY_NAME = profile_s
|
||||
FORCE_STATIC_LIB = 1
|
||||
|
||||
REQUIRES = \
|
||||
xpcom \
|
||||
string \
|
||||
appcomps \
|
||||
$(NULL)
|
||||
|
||||
LOCAL_INCLUDES = \
|
||||
-I$(srcdir)/../../xre \
|
||||
-I$(topsrcdir)/profile/dirserviceprovider/src \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
nsProfileLock.cpp \
|
||||
nsToolkitProfileService.cpp \
|
||||
nsINIParser.cpp \
|
||||
$(NULL)
|
||||
|
||||
GARBAGE += nsProfileLock.cpp
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
export:: $(topsrcdir)/profile/dirserviceprovider/src/nsProfileLock.cpp
|
||||
$(INSTALL) $^ .
|
|
@ -0,0 +1,253 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code,
|
||||
* released March 31, 1998.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Samir Gehani <sgehani@netscape.com>
|
||||
* Benjamin Smedberg <bsmedberg@covad.net>
|
||||
*/
|
||||
|
||||
|
||||
#include "nsINIParser.h"
|
||||
#include "nsError.h"
|
||||
#include "nsILocalFile.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
nsINIParser::nsINIParser() :
|
||||
mFileBuf(nsnull),
|
||||
mFileBufSize(0)
|
||||
{ }
|
||||
|
||||
nsresult
|
||||
nsINIParser::Init(nsILocalFile* aFile)
|
||||
{
|
||||
NS_ASSERTION(aFile, "Null param.");
|
||||
|
||||
nsresult rv;
|
||||
FILE *fd;
|
||||
long eofpos = 0;
|
||||
int rd = 0;
|
||||
|
||||
/* open the file */
|
||||
rv = aFile->OpenANSIFileDesc("r", &fd);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
/* get file size */
|
||||
if (fseek(fd, 0, SEEK_END) != 0) {
|
||||
rv = NS_BASE_STREAM_OSERROR;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
eofpos = ftell(fd);
|
||||
if (eofpos == 0) {
|
||||
rv = NS_BASE_STREAM_OSERROR;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/* malloc an internal buf the size of the file */
|
||||
mFileBuf = (char *) malloc((eofpos+1) * sizeof(char));
|
||||
if (!mFileBuf) {
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
mFileBufSize = eofpos;
|
||||
|
||||
/* read the file in one swoop */
|
||||
if (fseek(fd, 0, SEEK_SET) != 0) {
|
||||
rv = NS_BASE_STREAM_OSERROR;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
rd = fread((void *)mFileBuf, 1, eofpos, fd);
|
||||
if (!rd) {
|
||||
rv = NS_BASE_STREAM_OSERROR;
|
||||
goto bail;
|
||||
}
|
||||
mFileBuf[mFileBufSize] = '\0';
|
||||
|
||||
/* close file */
|
||||
fclose(fd);
|
||||
return NS_OK;
|
||||
|
||||
bail:
|
||||
if (fd)
|
||||
fclose(fd);
|
||||
|
||||
if (mFileBuf) {
|
||||
free(mFileBuf);
|
||||
mFileBuf = nsnull;
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsINIParser::~nsINIParser()
|
||||
{
|
||||
if (mFileBuf) {
|
||||
free(mFileBuf);
|
||||
mFileBuf = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsINIParser::GetString(const char *aSection, const char *aKey,
|
||||
char *aValBuf, PRUint32 aIOValBufSize)
|
||||
{
|
||||
NS_ASSERTION(aSection && aKey && aValBuf && aIOValBufSize,
|
||||
"Null param!");
|
||||
|
||||
nsresult rv;
|
||||
char *secPtr;
|
||||
|
||||
/* find the section if it exists */
|
||||
rv = FindSection(aSection, &secPtr);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
/* find the key if it exists in the valid section we found */
|
||||
rv = FindKey(secPtr, aKey, aValBuf, aIOValBufSize);
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsINIParser::FindSection(const char *aSection, char **aOutSecPtr)
|
||||
{
|
||||
char *currChar = mFileBuf;
|
||||
char *nextSec = nsnull;
|
||||
char *secClose = nsnull;
|
||||
char *nextNL = nsnull;
|
||||
int aSectionLen = strlen(aSection);
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
|
||||
while (currChar < (mFileBuf + mFileBufSize))
|
||||
{
|
||||
// look for first '['
|
||||
nextSec = NULL;
|
||||
nextSec = strchr(currChar, '[');
|
||||
if (!nextSec)
|
||||
break;
|
||||
|
||||
currChar = nextSec + 1;
|
||||
|
||||
// extract section name till first ']'
|
||||
secClose = NULL; nextNL = NULL;
|
||||
secClose = strchr(currChar, ']');
|
||||
nextNL = strchr(currChar, '\n');
|
||||
if ((!nextNL) || (nextNL < secClose))
|
||||
{
|
||||
currChar = nextNL;
|
||||
continue;
|
||||
}
|
||||
|
||||
// if section name matches we succeeded
|
||||
if (strncmp(aSection, currChar, aSectionLen) == 0
|
||||
&& secClose-currChar == aSectionLen)
|
||||
{
|
||||
*aOutSecPtr = secClose + 1;
|
||||
rv = NS_OK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsINIParser::FindKey(const char *aSecPtr, const char *aKey, char *aVal, int aIOValSize)
|
||||
{
|
||||
const char *nextNL = nsnull;
|
||||
const char *secEnd = nsnull;
|
||||
const char *currLine = aSecPtr;
|
||||
const char *nextEq = nsnull;
|
||||
int aKeyLen = strlen(aKey);
|
||||
|
||||
// determine the section end
|
||||
secEnd = aSecPtr;
|
||||
find_end:
|
||||
if (secEnd)
|
||||
secEnd = strchr(secEnd, '['); // search for next sec start
|
||||
if (!secEnd)
|
||||
{
|
||||
secEnd = strchr(aSecPtr, '\0'); // else search for file end
|
||||
if (!secEnd)
|
||||
{
|
||||
return NS_ERROR_FILE_CORRUPTED;
|
||||
}
|
||||
}
|
||||
|
||||
// handle start section token ('[') in values for i18n
|
||||
if (*secEnd == '[' && !(secEnd == aSecPtr || *(secEnd-1) == '\n'))
|
||||
{
|
||||
secEnd++;
|
||||
goto find_end;
|
||||
}
|
||||
|
||||
while (currLine < secEnd)
|
||||
{
|
||||
nextNL = NULL;
|
||||
nextNL = strchr(currLine, '\n');
|
||||
if (!nextNL)
|
||||
nextNL = mFileBuf + mFileBufSize;
|
||||
|
||||
// ignore commented lines (starting with ;)
|
||||
if (currLine == strchr(currLine, ';'))
|
||||
{
|
||||
currLine = nextNL + 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
// extract key before '='
|
||||
nextEq = NULL;
|
||||
nextEq = strchr(currLine, '=');
|
||||
if (!nextEq || nextEq > nextNL)
|
||||
{
|
||||
currLine = nextNL + 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
// if key matches we succeeded
|
||||
if (strncmp(currLine, aKey, aKeyLen) == 0
|
||||
&& nextEq-currLine == aKeyLen)
|
||||
{
|
||||
// extract the value and return
|
||||
if (aIOValSize < nextNL - nextEq)
|
||||
{
|
||||
*aVal = '\0';
|
||||
return NS_ERROR_LOSS_OF_SIGNIFICANT_DATA;
|
||||
}
|
||||
|
||||
PRUint32 len = nextNL - (nextEq + 1);
|
||||
|
||||
// allows win32-style \r\n line endings
|
||||
if ( *(nextEq + len) == '\r' )
|
||||
--len;
|
||||
|
||||
strncpy(aVal, (nextEq + 1), len);
|
||||
*(aVal + len) = 0; // null terminate
|
||||
return NS_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
currLine = nextNL + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code,
|
||||
* released March 31, 1998.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Samir Gehani <sgehani@netscape.com>
|
||||
* Benjamin Smedberg <bsmedberg@covad.net>
|
||||
*
|
||||
* This file was shamelessly copied from mozilla/xpinstall/wizard/unix/src2
|
||||
*/
|
||||
|
||||
#ifndef nsINIParser_h__
|
||||
#define nsINIParser_h__
|
||||
|
||||
#include "nscore.h"
|
||||
|
||||
// hack alert: in static builds, nsINIParser here conflicts with nsINIParser
|
||||
// in browser/components/migration. So we use a #define to make the symbols
|
||||
// unique.
|
||||
#define nsINIParser nsINITParser
|
||||
|
||||
class nsILocalFile;
|
||||
|
||||
class nsINIParser
|
||||
{
|
||||
public:
|
||||
nsINIParser();
|
||||
~nsINIParser();
|
||||
|
||||
#if 0 // use nsresult instead
|
||||
/**
|
||||
* Errors
|
||||
*/
|
||||
enum INIResult
|
||||
{
|
||||
OK = 0,
|
||||
E_READ = -701,
|
||||
E_MEM = -702,
|
||||
E_PARAM = -703,
|
||||
E_NO_SEC = -704,
|
||||
E_NO_KEY = -705,
|
||||
E_SEC_CORRUPT = -706,
|
||||
E_SMALL_BUF = -707
|
||||
};
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Initialize the INIParser with a nsILocalFile. If this method fails, no
|
||||
* other methods should be called.
|
||||
*/
|
||||
nsresult Init(nsILocalFile* aFile);
|
||||
|
||||
/**
|
||||
* GetString
|
||||
*
|
||||
* Gets the value of the specified key in the specified section
|
||||
* of the INI file represented by this instance. The value is stored
|
||||
* in the supplied buffer. The buffer size is provided as input and
|
||||
* the actual bytes used by the value is set in the in/out size param.
|
||||
*
|
||||
* @param aSection section name
|
||||
* @param aKey key name
|
||||
* @param aValBuf user supplied buffer
|
||||
* @param aIOValBufSize buf size on input; actual buf used on output
|
||||
*
|
||||
* @return mError operation success code
|
||||
*/
|
||||
nsresult GetString(const char *aSection, const char *aKey,
|
||||
char *aValBuf, PRUint32 aIOValBufSize );
|
||||
|
||||
private:
|
||||
nsresult FindSection(const char *aSection, char **aOutSecPtr);
|
||||
nsresult FindKey(const char *aSecPtr, const char *aKey,
|
||||
char *aVal, int aIOValSize);
|
||||
|
||||
char *mFileBuf;
|
||||
int mFileBufSize;
|
||||
};
|
||||
|
||||
#endif /* nsINIParser_h__ */
|
|
@ -0,0 +1,820 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the new Mozilla toolkit.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Benjamin Smedberg <bsmedberg@covad.net>
|
||||
* Portions created by the Initial Developer are Copyright (C) 2004
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "nsProfileLock.h"
|
||||
|
||||
#ifdef XP_WIN
|
||||
#include <windows.h>
|
||||
#include <shlobj.h>
|
||||
#endif
|
||||
#ifdef XP_BEOS
|
||||
#include <Path.h>
|
||||
#endif
|
||||
#ifdef XP_UNIX
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "nsIToolkitProfileService.h"
|
||||
#include "nsIToolkitProfile.h"
|
||||
#include "nsIFactory.h"
|
||||
#include "nsILocalFile.h"
|
||||
#include "nsISimpleEnumerator.h"
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
#include <CFURL.h>
|
||||
#include "nsILocalFileMac.h"
|
||||
#endif
|
||||
|
||||
#include "nsAppDirectoryServiceDefs.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
|
||||
#include "nsINIParser.h"
|
||||
#include "nsXREDirProvider.h"
|
||||
#include "nsAppRunner.h"
|
||||
#include "nsString.h"
|
||||
#include "nsReadableUtils.h"
|
||||
|
||||
|
||||
class nsToolkitProfile : public nsIToolkitProfile
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSITOOLKITPROFILE
|
||||
|
||||
friend class nsToolkitProfileService;
|
||||
nsCOMPtr<nsToolkitProfile> mNext;
|
||||
nsToolkitProfile *mPrev;
|
||||
|
||||
private:
|
||||
nsToolkitProfile(const nsACString& aName, nsILocalFile* aFile,
|
||||
nsToolkitProfile* aPrev);
|
||||
~nsToolkitProfile() { }
|
||||
|
||||
friend class nsToolkitProfileLock;
|
||||
|
||||
nsCString mName;
|
||||
nsCOMPtr<nsILocalFile> mFile;
|
||||
nsIProfileLock* mLock;
|
||||
};
|
||||
|
||||
class nsToolkitProfileLock : public nsIProfileLock
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIPROFILELOCK
|
||||
|
||||
nsresult Init(nsToolkitProfile* aProfile);
|
||||
nsresult Init(nsILocalFile* aDirectory);
|
||||
|
||||
nsToolkitProfileLock() { }
|
||||
|
||||
private:
|
||||
~nsToolkitProfileLock();
|
||||
|
||||
nsCOMPtr<nsToolkitProfile> mProfile;
|
||||
nsCOMPtr<nsILocalFile> mDirectory;
|
||||
|
||||
nsProfileLock mLock;
|
||||
};
|
||||
|
||||
class nsToolkitProfileService : public nsIToolkitProfileService,
|
||||
public nsIFactory
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSITOOLKITPROFILESERVICE
|
||||
|
||||
// we implement nsIFactory because we can't be registered by location,
|
||||
// like most ordinary components are. Instead, during startup we register
|
||||
// our factory. Then we return our singleton-self when asked.
|
||||
NS_DECL_NSIFACTORY
|
||||
|
||||
private:
|
||||
friend class nsToolkitProfile;
|
||||
friend nsresult NS_NewToolkitProfileService(nsIToolkitProfileService**);
|
||||
|
||||
nsToolkitProfileService() :
|
||||
mDirty(PR_FALSE),
|
||||
mStartWithLast(PR_TRUE),
|
||||
mStartOffline(PR_FALSE)
|
||||
{
|
||||
gService = this;
|
||||
}
|
||||
~nsToolkitProfileService()
|
||||
{
|
||||
gService = nsnull;
|
||||
}
|
||||
|
||||
NS_HIDDEN_(nsresult) Init();
|
||||
|
||||
nsCOMPtr<nsToolkitProfile> mFirst;
|
||||
nsCOMPtr<nsToolkitProfile> mChosen;
|
||||
nsCOMPtr<nsILocalFile> mAppData;
|
||||
nsCOMPtr<nsILocalFile> mListFile;
|
||||
PRBool mDirty;
|
||||
PRBool mStartWithLast;
|
||||
PRBool mStartOffline;
|
||||
|
||||
static nsToolkitProfileService *gService;
|
||||
|
||||
class ProfileEnumerator : public nsISimpleEnumerator
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSISIMPLEENUMERATOR
|
||||
|
||||
ProfileEnumerator(nsToolkitProfile *first)
|
||||
{ mCurrent = first; }
|
||||
private:
|
||||
~ProfileEnumerator() { }
|
||||
nsCOMPtr<nsToolkitProfile> mCurrent;
|
||||
};
|
||||
};
|
||||
|
||||
nsToolkitProfile::nsToolkitProfile(const nsACString& aName, nsILocalFile* aFile,
|
||||
nsToolkitProfile* aPrev) :
|
||||
mPrev(aPrev),
|
||||
mName(aName),
|
||||
mFile(aFile),
|
||||
mLock(nsnull)
|
||||
{
|
||||
NS_ASSERTION(aFile, "No file!");
|
||||
|
||||
if (aPrev)
|
||||
aPrev->mNext = this;
|
||||
else
|
||||
nsToolkitProfileService::gService->mFirst = this;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsToolkitProfile, nsIToolkitProfile)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsToolkitProfile::GetRootDir(nsILocalFile* *aResult)
|
||||
{
|
||||
NS_ADDREF(*aResult = mFile);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsToolkitProfile::GetName(nsACString& aResult)
|
||||
{
|
||||
aResult = mName;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsToolkitProfile::SetName(const nsACString& aName)
|
||||
{
|
||||
NS_ASSERTION(nsToolkitProfileService::gService,
|
||||
"Where did my service go?");
|
||||
|
||||
mName = aName;
|
||||
nsToolkitProfileService::gService->mDirty = PR_TRUE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsToolkitProfile::Remove(PRBool removeFiles)
|
||||
{
|
||||
NS_ASSERTION(nsToolkitProfileService::gService,
|
||||
"Whoa, my service is gone.");
|
||||
|
||||
if (mLock)
|
||||
return NS_ERROR_FILE_IS_LOCKED;
|
||||
|
||||
if (removeFiles)
|
||||
mFile->Remove(PR_TRUE);
|
||||
|
||||
if (mPrev)
|
||||
mPrev->mNext = mNext;
|
||||
else
|
||||
nsToolkitProfileService::gService->mFirst = mNext;
|
||||
|
||||
if (mNext)
|
||||
mNext->mPrev = mPrev;
|
||||
|
||||
mPrev = nsnull;
|
||||
mNext = nsnull;
|
||||
|
||||
if (nsToolkitProfileService::gService->mChosen == this)
|
||||
nsToolkitProfileService::gService = nsnull;
|
||||
|
||||
nsToolkitProfileService::gService->mDirty = PR_TRUE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsToolkitProfile::Lock(nsIProfileLock* *aResult)
|
||||
{
|
||||
if (mLock) {
|
||||
NS_ADDREF(*aResult = mLock);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsToolkitProfileLock> lock = new nsToolkitProfileLock();
|
||||
if (!lock) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
nsresult rv = lock->Init(this);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
NS_ADDREF(*aResult = lock);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsToolkitProfileLock, nsIProfileLock)
|
||||
|
||||
nsresult
|
||||
nsToolkitProfileLock::Init(nsToolkitProfile* aProfile)
|
||||
{
|
||||
nsresult rv;
|
||||
rv = Init(aProfile->mFile);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
mProfile = aProfile;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsToolkitProfileLock::Init(nsILocalFile* aDirectory)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
rv = mLock.Lock(aDirectory);
|
||||
|
||||
if (NS_SUCCEEDED(rv))
|
||||
mDirectory = aDirectory;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsToolkitProfileLock::GetDirectory(nsILocalFile* *aResult)
|
||||
{
|
||||
if (!mDirectory) {
|
||||
NS_ERROR("Not initialized, or unlocked!");
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
NS_ADDREF(*aResult = mDirectory);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsToolkitProfileLock::Unlock()
|
||||
{
|
||||
if (!mDirectory) {
|
||||
NS_ERROR("Unlocking a never-locked nsToolkitProfileLock!");
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
mLock.Unlock();
|
||||
|
||||
if (mProfile) {
|
||||
mProfile->mLock = nsnull;
|
||||
mProfile = nsnull;
|
||||
}
|
||||
mDirectory = nsnull;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsToolkitProfileLock::~nsToolkitProfileLock()
|
||||
{
|
||||
if (mDirectory) {
|
||||
Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
nsToolkitProfileService*
|
||||
nsToolkitProfileService::gService = nsnull;
|
||||
|
||||
NS_IMPL_ISUPPORTS2(nsToolkitProfileService,
|
||||
nsIToolkitProfileService,
|
||||
nsIFactory)
|
||||
|
||||
nsresult
|
||||
nsToolkitProfileService::Init()
|
||||
{
|
||||
NS_ASSERTION(gDirServiceProvider, "No dirserviceprovider!");
|
||||
nsresult rv;
|
||||
|
||||
rv = gDirServiceProvider->GetUserAppDataDirectory(getter_AddRefs(mAppData));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIFile> listFile;
|
||||
rv = mAppData->Clone(getter_AddRefs(listFile));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mListFile = do_QueryInterface(listFile);
|
||||
NS_ENSURE_TRUE(listFile, NS_ERROR_NO_INTERFACE);
|
||||
|
||||
rv = mListFile->AppendNative(NS_LITERAL_CSTRING("profiles.ini"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRBool exists;
|
||||
rv = mListFile->IsFile(&exists);
|
||||
if (NS_FAILED(rv) || !exists) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsINIParser parser;
|
||||
rv = parser.Init(mListFile);
|
||||
// Parsing errors are troublesome... we're gonna continue even on
|
||||
// parsing errors, and let people manually re-locate their profile
|
||||
// if something goes wacky
|
||||
|
||||
char parserBuf[MAXPATHLEN];
|
||||
rv = parser.GetString("General", "StartWithLastProfile", parserBuf, MAXPATHLEN);
|
||||
if (NS_SUCCEEDED(rv) && strcmp("0", parserBuf) == 0)
|
||||
mStartWithLast = PR_FALSE;
|
||||
|
||||
nsToolkitProfile* currentProfile = nsnull;
|
||||
nsCAutoString filePath;
|
||||
|
||||
unsigned int c = 0;
|
||||
for (c = 0; PR_TRUE; ++c) {
|
||||
char profileID[12];
|
||||
sprintf(profileID, "Profile%u", c);
|
||||
|
||||
rv = parser.GetString(profileID, "IsRelative", parserBuf, MAXPATHLEN);
|
||||
if (NS_FAILED(rv)) break;
|
||||
|
||||
PRBool isRelative = (strcmp(parserBuf, "1") == 0);
|
||||
|
||||
rv = parser.GetString(profileID, "Path", parserBuf, MAXPATHLEN);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_ERROR("Malformed profiles.ini: Path= not found");
|
||||
continue;
|
||||
}
|
||||
|
||||
filePath = parserBuf;
|
||||
|
||||
rv = parser.GetString(profileID, "Name", parserBuf, MAXPATHLEN);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_ERROR("Malformed profiles.ini: Name= not found");
|
||||
continue;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsILocalFile> rootDir;
|
||||
rv = NS_NewNativeLocalFile(EmptyCString(), PR_TRUE,
|
||||
getter_AddRefs(rootDir));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (isRelative) {
|
||||
rv = rootDir->SetRelativeDescriptor(mAppData, filePath);
|
||||
} else {
|
||||
rv = rootDir->SetPersistentDescriptor(filePath);
|
||||
}
|
||||
if (NS_FAILED(rv)) continue;
|
||||
|
||||
currentProfile = new nsToolkitProfile(nsDependentCString(parserBuf),
|
||||
rootDir, currentProfile);
|
||||
NS_ENSURE_TRUE(currentProfile, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
rv = parser.GetString(profileID, "Default", parserBuf, MAXPATHLEN);
|
||||
if (NS_SUCCEEDED(rv) && strcmp("1", parserBuf) == 0)
|
||||
mChosen = currentProfile;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsToolkitProfileService::SetStartWithLastProfile(PRBool aValue)
|
||||
{
|
||||
if (mStartWithLast != aValue) {
|
||||
mStartWithLast = aValue;
|
||||
mDirty = PR_TRUE;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsToolkitProfileService::GetStartWithLastProfile(PRBool *aResult)
|
||||
{
|
||||
*aResult = mStartWithLast;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsToolkitProfileService::GetStartOffline(PRBool *aResult)
|
||||
{
|
||||
*aResult = mStartOffline;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsToolkitProfileService::SetStartOffline(PRBool aValue)
|
||||
{
|
||||
mStartOffline = aValue;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsToolkitProfileService::GetProfiles(nsISimpleEnumerator* *aResult)
|
||||
{
|
||||
*aResult = new ProfileEnumerator(this->mFirst);
|
||||
if (!*aResult)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(*aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsToolkitProfileService::ProfileEnumerator,
|
||||
nsISimpleEnumerator)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsToolkitProfileService::ProfileEnumerator::HasMoreElements(PRBool* aResult)
|
||||
{
|
||||
*aResult = mCurrent ? PR_TRUE : PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsToolkitProfileService::ProfileEnumerator::GetNext(nsISupports* *aResult)
|
||||
{
|
||||
if (!mCurrent) return NS_ERROR_FAILURE;
|
||||
|
||||
NS_ADDREF(*aResult = mCurrent);
|
||||
|
||||
mCurrent = mCurrent->mNext;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsToolkitProfileService::GetSelectedProfile(nsIToolkitProfile* *aResult)
|
||||
{
|
||||
if (!mChosen && mFirst && !mFirst->mNext) // only one profile
|
||||
mChosen = mFirst;
|
||||
|
||||
if (!mChosen) return NS_ERROR_FAILURE;
|
||||
|
||||
NS_ADDREF(*aResult = mChosen);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsToolkitProfileService::SetSelectedProfile(nsIToolkitProfile* aProfile)
|
||||
{
|
||||
if (mChosen != aProfile) {
|
||||
mChosen = aProfile;
|
||||
mDirty = PR_TRUE;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsToolkitProfileService::GetProfileByName(const nsACString& aName,
|
||||
nsIToolkitProfile* *aResult)
|
||||
{
|
||||
nsToolkitProfile* curP = mFirst;
|
||||
while (curP) {
|
||||
if (curP->mName.Equals(aName)) {
|
||||
NS_ADDREF(*aResult = curP);
|
||||
return NS_OK;
|
||||
}
|
||||
curP = curP->mNext;
|
||||
}
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsToolkitProfileService::LockProfilePath(nsILocalFile* aDirectory,
|
||||
nsIProfileLock* *aResult)
|
||||
{
|
||||
return NS_LockProfilePath(aDirectory, aResult);
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_LockProfilePath(nsILocalFile* aPath, nsIProfileLock* *aResult)
|
||||
{
|
||||
nsCOMPtr<nsToolkitProfileLock> lock = new nsToolkitProfileLock();
|
||||
if (!lock) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
nsresult rv = lock->Init(aPath);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
NS_ADDREF(*aResult = lock);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static const char kTable[] =
|
||||
{ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
|
||||
'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
|
||||
'1', '2', '3', '4', '5', '6', '7', '8', '9', '0' };
|
||||
|
||||
static void SaltProfileName(nsACString& aName)
|
||||
{
|
||||
double fpTime;
|
||||
LL_L2D(fpTime, PR_Now());
|
||||
|
||||
// use 1e-6, granularity of PR_Now() on the mac is seconds
|
||||
srand((uint)(fpTime * 1e-6 + 0.5));
|
||||
|
||||
aName.Append('.');
|
||||
int i;
|
||||
for (i = 0; i < 3; ++i)
|
||||
aName.Append(kTable[rand() % NS_ARRAY_LENGTH(kTable)]);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsToolkitProfileService::CreateProfile(nsILocalFile* aRootDir,
|
||||
const nsACString& aName,
|
||||
nsIToolkitProfile* *aResult)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
rv = GetProfileByName(aName, aResult);
|
||||
if (NS_SUCCEEDED(rv)) return rv;
|
||||
|
||||
nsCOMPtr<nsILocalFile> rootDir (aRootDir);
|
||||
|
||||
if (!rootDir) {
|
||||
nsCOMPtr<nsIFile> file;
|
||||
PRBool dummy;
|
||||
rv = gDirServiceProvider->GetFile(NS_APP_USER_PROFILES_ROOT_DIR, &dummy,
|
||||
getter_AddRefs(file));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rootDir = do_QueryInterface(file);
|
||||
NS_ENSURE_TRUE(rootDir, NS_ERROR_UNEXPECTED);
|
||||
|
||||
nsCAutoString dirName(aName);
|
||||
SaltProfileName(dirName);
|
||||
|
||||
rootDir->AppendNative(dirName);
|
||||
}
|
||||
|
||||
PRBool exists;
|
||||
rv = rootDir->Exists(&exists);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (exists) {
|
||||
rv = rootDir->IsDirectory(&exists);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!exists)
|
||||
return NS_ERROR_FILE_NOT_DIRECTORY;
|
||||
}
|
||||
else {
|
||||
nsCOMPtr<nsIFile> profileDefaultsDir;
|
||||
nsCOMPtr<nsIFile> profileDirParent;
|
||||
nsCAutoString profileDirName;
|
||||
|
||||
rv = rootDir->GetParent(getter_AddRefs(profileDirParent));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = rootDir->GetNativeLeafName(profileDirName);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRBool dummy;
|
||||
rv = gDirServiceProvider->GetFile(NS_APP_PROFILE_DEFAULTS_50_DIR, &dummy,
|
||||
getter_AddRefs(profileDefaultsDir));
|
||||
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = profileDefaultsDir->CopyToNative(profileDirParent,
|
||||
profileDirName);
|
||||
if (NS_FAILED(rv)) {
|
||||
// if copying failed, lets just ensure that the profile directory exists.
|
||||
rv = rootDir->Create(nsIFile::DIRECTORY_TYPE, 0700);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
rv = rootDir->SetPermissions(0700);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
nsToolkitProfile* last = mFirst;
|
||||
if (last) {
|
||||
while (last->mNext)
|
||||
last = last->mNext;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIToolkitProfile> profile =
|
||||
new nsToolkitProfile(aName, rootDir, last);
|
||||
if (!profile) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(*aResult = profile);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsToolkitProfileService::GetProfileCount(PRUint32 *aResult)
|
||||
{
|
||||
if (!mFirst)
|
||||
*aResult = 0;
|
||||
else if (! mFirst->mNext)
|
||||
*aResult = 1;
|
||||
else
|
||||
*aResult = 2;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsToolkitProfileService::Flush()
|
||||
{
|
||||
// Errors during writing might cause unhappy semi-written files.
|
||||
// To avoid this, write the entire thing to a buffer, then write
|
||||
// that buffer to disk.
|
||||
|
||||
nsresult rv;
|
||||
PRUint32 pCount = 0;
|
||||
nsToolkitProfile *cur;
|
||||
|
||||
for (cur = mFirst; cur != nsnull; cur = cur->mNext)
|
||||
++pCount;
|
||||
|
||||
PRUint32 length;
|
||||
|
||||
char* buffer = (char*) malloc(100 + MAXPATHLEN * pCount);
|
||||
NS_ENSURE_TRUE(buffer, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
char *end = buffer;
|
||||
|
||||
end += sprintf(end,
|
||||
"[General]\n"
|
||||
"StartWithLastProfile=%s\n\n",
|
||||
mStartWithLast ? "1" : "0");
|
||||
|
||||
nsCAutoString path;
|
||||
cur = mFirst;
|
||||
pCount = 0;
|
||||
|
||||
while (cur) {
|
||||
// if the profile dir is relative to appdir...
|
||||
PRBool isRelative;
|
||||
rv = mAppData->Contains(cur->mFile, PR_TRUE, &isRelative);
|
||||
if (NS_SUCCEEDED(rv) && isRelative) {
|
||||
// we use a relative descriptor
|
||||
rv = cur->mFile->GetRelativeDescriptor(mAppData, path);
|
||||
} else {
|
||||
// otherwise, a persistent descriptor
|
||||
rv = cur->mFile->GetPersistentDescriptor(path);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
end += sprintf(end,
|
||||
"[Profile%u]\n"
|
||||
"Name=%s\n"
|
||||
"IsRelative=%s\n"
|
||||
"Path=%s\n",
|
||||
pCount, cur->mName.get(),
|
||||
isRelative ? "1" : "0", path.get());
|
||||
|
||||
if (mChosen == cur) {
|
||||
end += sprintf(end, "Default=1\n");
|
||||
}
|
||||
|
||||
end += sprintf(end, "\n");
|
||||
|
||||
cur = cur->mNext;
|
||||
++pCount;
|
||||
}
|
||||
|
||||
FILE* writeFile;
|
||||
rv = mListFile->OpenANSIFileDesc("w", &writeFile);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (buffer) {
|
||||
length = end - buffer;
|
||||
|
||||
if (fwrite(buffer, sizeof(char), length, writeFile) != length) {
|
||||
fclose(writeFile);
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(writeFile);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsToolkitProfileService::CreateInstance(nsISupports* aOuter, const nsID& aIID,
|
||||
void** aResult)
|
||||
{
|
||||
if (aOuter)
|
||||
return NS_ERROR_NO_AGGREGATION;
|
||||
|
||||
// return this object
|
||||
return QueryInterface(aIID, aResult);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsToolkitProfileService::LockFactory(PRBool aVal)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_NewToolkitProfileService(nsIToolkitProfileService* *aResult)
|
||||
{
|
||||
nsToolkitProfileService* aThis = new nsToolkitProfileService();
|
||||
nsresult rv = aThis->Init();
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_ERROR("nsToolkitProfileService::Init failed!");
|
||||
delete aThis;
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_ADDREF(*aResult = aThis);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_GetFileFromPath(const char *aPath, nsILocalFile* *aResult)
|
||||
{
|
||||
#if defined(XP_MACOSX)
|
||||
PRInt32 pathLen = strlen(aPath);
|
||||
if (pathLen > MAXPATHLEN)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
CFURLRef fullPath =
|
||||
CFURLCreateFromFileSystemRepresentation(NULL, aPath, pathLen, true);
|
||||
if (!fullPath)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsILocalFile> lf;
|
||||
nsresult rv = NS_NewNativeLocalFile(EmptyCString(), PR_TRUE,
|
||||
getter_AddRefs(lf));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCOMPtr<nsILocalFileMac> lfMac = do_QueryInterface(lf, &rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = lfMac->InitWithCFURL(fullPath);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
NS_ADDREF(*aResult = lf);
|
||||
}
|
||||
}
|
||||
CFRelease(fullPath);
|
||||
return rv;
|
||||
|
||||
#elif defined(XP_UNIX) || defined(XP_OS2)
|
||||
char fullPath[MAXPATHLEN];
|
||||
|
||||
if (!realpath(aPath, fullPath))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return NS_NewNativeLocalFile(nsDependentCString(fullPath), PR_TRUE,
|
||||
aResult);
|
||||
|
||||
#elif defined(XP_WIN)
|
||||
char fullPath[MAXPATHLEN];
|
||||
|
||||
if (!_fullpath(fullPath, aPath, MAXPATHLEN))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return NS_NewNativeLocalFile(nsDependentCString(fullPath), PR_TRUE,
|
||||
aResult);
|
||||
|
||||
#elif defined(XP_BEOS)
|
||||
BPath fullPath;
|
||||
if (fullPath.SetTo(aPath, NULL, true))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return NS_NewNativeLocalFile(nsDependentCString(fullPath.Leaf()), PR_TRUE,
|
||||
aResult);
|
||||
|
||||
#else
|
||||
#error Platform-specific logic needed here.
|
||||
#endif
|
||||
}
|
Загрузка…
Ссылка в новой задаче