This commit is contained in:
mcmullen%netscape.com 1999-06-04 23:32:03 +00:00
Родитель 8da737b78e
Коммит 105c00d0f7
5 изменённых файлов: 781 добавлений и 76 удалений

Двоичный файл не отображается.

Просмотреть файл

@ -21,11 +21,14 @@
%{ C++
#include "nscore.h" // for PRUnichar
class nsIDOMWindow;
#define PREFWINDOW_MAX_STRINGS 10
%}
[scriptable, uuid(55AF8384-E11E-11D2-915F-A053F05FF7BC)]
interface nsIPrefWindow : nsISupports
{
void Init(in wstring id);
void ShowWindow(in nsIDOMWindow currentFrontWin);
void ChangePanel(in wstring url);
@ -37,9 +40,9 @@ interface nsIPrefWindow : nsISupports
};
%{ C++
// {11185200-19c3-11d3-915f-ff93af9fa9fc}
// {CFC599F0-04CA-11d3-8068-00600811A9C3}
#define NS_PREFWINDOW_CID \
{ 0x11185200, 0x19c3, 0x11d3, { 0x91, 0x5f, 0xff, 0x93, 0xaf, 0x9f, 0xa9, 0xfc } }
{ 0xcfc599f0, 0x4ca, 0x11d3, { 0x80, 0x68, 0x0, 0x60, 0x8, 0x11, 0xa9, 0xc3 } }
#define NS_PREFWINDOW_PROGID \
"component://netscape/prefwindow"

Просмотреть файл

@ -26,7 +26,7 @@ MODULE=mozsampl
LIBRARY_NAME=mozsampl
IS_COMPONENT=1
CPPSRCS= \
nsSampleAppShellComponent.cpp \
nsPrefWindow.cpp \
$(NULL)
EXTRA_DSO_LDOPTS = \

Просмотреть файл

@ -56,7 +56,7 @@ LLIBS = \
#//
#//------------------------------------------------------------------------
OBJS = \
.\$(OBJDIR)\nsSampleAppShellComponent.obj \
.\$(OBJDIR)\nsPrefWindow.obj \
$(NULL)
#//------------------------------------------------------------------------

Просмотреть файл

@ -1,91 +1,793 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
/* -*- 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.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* Version 1.0 (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 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.
* 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 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.
* The Original Code is Mozilla Communicator client 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.
*/
#include "nsIPrefWindow.h"
#include "nsIAppShellComponentImpl.h"
#include "nsPrefWindow.h"
#if 0
#include "nsCOMPtr.h"
#include "nsIPref.h"
#include "nsIURL.h"
#include "nsIFileLocator.h"
#include "nsFileLocations.h"
#include "nsFileSpec.h"
#include "nsFileStream.h"
#include "nsIBrowserWindow.h"
#include "nsIWebShell.h"
#include "pratom.h"
#include "nsIFactory.h"
#include "nsIComponentManager.h"
#include "nsIServiceManager.h"
#include "nsIAppShellService.h"
#include "prprf.h"
#include "nsAppShellCIDs.h"
#include "nsIXULWindowCallbacks.h"
#include "nsIDocumentObserver.h"
#include "nsString.h"
#include "nsIURL.h"
#include "nsIWebShellWindow.h"
#include "nsIContent.h"
#include "nsINameSpaceManager.h"
#include "nsIContentViewer.h"
#include "nsIDocumentViewer.h"
#include "nsIWebShell.h"
#include "nsIScriptGlobalObject.h"
#include "nsIScriptContext.h"
#include "nsIScriptContextOwner.h"
#include "nsIDOMDocument.h"
#include "nsIDocument.h"
#include "nsIDOMXULDocument.h"
#include "nsIDOMElement.h"
#include "nsIStreamTransfer.h"
#include "nsIDOMWindow.h"
#include "nsIWebShellWindow.h"
#include "nsIDOMHTMLInputElement.h"
#include "plstr.h"
#include "prprf.h"
#include "prmem.h"
#include <ctype.h>
// Globals - how many K are we wasting by putting these in every file?
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kIDOMDocumentIID, nsIDOMDocument::GetIID());
static NS_DEFINE_IID(kIDocumentIID, nsIDocument::GetIID());
static NS_DEFINE_IID(kIPrefIID, NS_IPREF_IID);
static NS_DEFINE_CID(kPrefCID, NS_PREF_CID);
static NS_DEFINE_IID(kIFileLocatorIID, NS_IFILELOCATOR_IID);
static NS_DEFINE_IID(kAppShellServiceCID, NS_APPSHELL_SERVICE_CID);
static NS_DEFINE_CID(kFileLocatorCID, NS_FILELOCATOR_CID);
#ifdef NS_DEBUG
static PRBool firstTime = PR_TRUE;
#endif
// You'll have to generate your own CID for your component...
// {CFC599F0-04CA-11d3-8068-00600811A9C3}
#define NS_PREFWINDOW_CID \
{ 0xcfc599f0, 0x4ca, 0x11d3, { 0x80, 0x68, 0x0, 0x60, 0x8, 0x11, 0xa9, 0xc3 } }
static void DOMWindowToWebShellWindow(nsIDOMWindow *DOMWindow, nsCOMPtr<nsIWebShellWindow> *webWindow);
// Implementation of the sample app shell component interface.
class nsPrefWindow : public nsIPrefWindow,
public nsAppShellComponentImpl {
public:
NS_DEFINE_STATIC_CID_ACCESSOR( NS_PREFWINDOW_CID );
//----------------------------------------------------------------------------------------
nsPrefWindow::nsPrefWindow()
//----------------------------------------------------------------------------------------
: mTreeWindow(nsnull)
, mPanelWindow(nsnull)
, mPrefs(nsnull)
, mSubStrings(nsnull)
{
NS_INIT_REFCNT();
printf("Created nsPrefWindow\n");
#ifdef NS_DEBUG
NS_ASSERTION(firstTime, "There can be only one");
firstTime = PR_FALSE;
#endif
// ctor/dtor
nsPrefWindow() {
NS_INIT_REFCNT();
// initialize substrings to null
mSubStrings = new char*[PREFWINDOW_MAX_STRINGS+1];
for (int i=0; i < PREFWINDOW_MAX_STRINGS; i++)
mSubStrings[i]=nsnull;
mSubStrings[PREFWINDOW_MAX_STRINGS] = nsnull;
} // nsPrefWindow::nsPrefWindow
//----------------------------------------------------------------------------------------
nsPrefWindow::~nsPrefWindow()
//----------------------------------------------------------------------------------------
{
NS_IF_RELEASE(mTreeWindow);
NS_IF_RELEASE(mPanelWindow);
nsServiceManager::ReleaseService(kPrefCID, mPrefs);
if (mSubStrings)
{
for (int i=0; i< PREFWINDOW_MAX_STRINGS; i++)
if (mSubStrings[i])
delete[] mSubStrings[i];
delete[] mSubStrings;
}
virtual ~nsPrefWindow() {
}
// This class implements the nsISupports interface functions.
NS_DECL_ISUPPORTS
// This class implements the nsIAppShellComponent interface functions.
NS_DECL_IAPPSHELLCOMPONENT
// This class implements the nsIPrefWindow interface functions.
NS_DECL_IPREFWINDOW
private:
// Data members and implemention functions go here.
// Objects of this class are counted to manage library unloading...
nsInstanceCounter instanceCounter;
}; // nsPrefWindow
NS_IMETHODIMP
nsPrefWindow::DoDialogTests() {
nsresult rv = NS_OK;
DEBUG_PRINTF( PR_STDOUT, "nsPrefWindow::DoDialogTests called\n" );
return rv;
#ifdef NS_DEBUG
firstTime = PR_TRUE;
#endif
}
// Generate base nsIAppShellComponent implementation.
NS_IMPL_IAPPSHELLCOMPONENT( nsPrefWindow,
nsIPrefWindow,
NS_IPREFWINDOW_PROGID )
NS_IMPL_ISUPPORTS(nsPrefWindow, nsPrefWindow::GetIID())
//----------------------------------------------------------------------------------------
NS_IMETHODIMP nsPrefWindow::Init(const PRUnichar* aID)
//----------------------------------------------------------------------------------------
{
#ifdef NS_DEBUG
nsOutputConsoleStream stream;
char buf[512];
stream << nsString(aID).ToCString(buf, sizeof(buf)) << " initialized";
#endif
nsresult rv;
NS_WITH_SERVICE(nsIPref, prefs, kPrefCID, &rv);
if (NS_FAILED(rv))
return rv;
if (!prefs)
return NS_ERROR_FAILURE;
#if 0
NS_WITH_SERVICE(nsIFileLocator, locator, kFileLocatorCID, &rv);
if (NS_FAILED(rv))
return rv;
if (!locator)
return NS_ERROR_FAILURE;
nsFileSpec newPrefs;
rv = locator->GetFileLocation(nsSpecialFileSpec::App_PreferencesFile50, &newPrefs);
#if 0
// Migration?
if (NS_FAILED(rv) || !newPrefs.Exists())
{
nsFileSpec oldPrefs;
rv = locator->GetFileLocation(App_PreferencesFile40, &oldPrefs);
if (NS_FAILED(rv) || !oldPrefs.Exists())
{
rv = locator->GetFileLocation(App_PreferencesFile30, &oldPrefs);
}
if (NS_SUCCEEDED(rv) && oldPrefs.Exists())
{
nsFileSpec newParent;
rv = locator->GetFileLocation(App_PrefsDirectory50, &newParent);
if (NS_SUCCEEDED(rv))
{
oldPrefs.Copy(newParent);
const char* oldName = oldPrefs.GetLeafName();
newPrefs = newParent + oldName;
PL_strfree(oldName);
newPrefs.Rename("prefs.js");
}
}
}
#endif
if (NS_SUCCEEDED(rv))
{
if (!newPrefs.Exists())
{
nsOutputFileStream stream(newPrefs);
if (stream.is_open())
{
stream << "// This is an empty prefs file" << nsEndl;
}
}
if (newPrefs.Exists())
rv = prefs->Startup(newPrefs.GetCString());
else
rv = NS_ERROR_FAILURE;
}
if (prefs && NS_FAILED(rv))
nsServiceManager::ReleaseService(kPrefCID, prefs);
if (NS_FAILED(rv))
return rv;
#endif // 0
mPrefs = prefs;
return NS_OK;
} // nsPrefWindow::Init()
//----------------------------------------------------------------------------------------
static PRBool CheckAndStrip(
nsString& ioString,
const char* inPrefix)
//----------------------------------------------------------------------------------------
{
if (ioString.Find(inPrefix) != 0)
return PR_FALSE;
ioString.Cut(0, PL_strlen(inPrefix));
return PR_TRUE;
}
//----------------------------------------------------------------------------------------
static PRInt16 CheckOrdinalAndStrip(nsString& ioString, PRInt16& outOrdinal)
//----------------------------------------------------------------------------------------
{
PRInt32 colonPos = ioString.Find(':');
if (colonPos <= 0)
return PR_FALSE;
char* intString = ioString.ToNewCString();
intString[colonPos] = 0;
if (!isdigit(*intString))
{
outOrdinal = 0;
return PR_TRUE;
}
ioString.Cut(0, colonPos + 1);
short result = 0;
sscanf(intString, "%hd", &result);
delete [] intString;
outOrdinal = result;
return PR_TRUE;
}
//----------------------------------------------------------------------------------------
static PRBool ParseElementIDString(
nsString& ioWidgetIDString,
nsPrefWindow::TypeOfPref& outType,
PRInt16& outOrdinal)
// If the id in the HTML is "pref:bool:general.startup.browser".
// outType will be set to eBool
// ioWidgetIDString will be modified to "general.startup.browser".
//----------------------------------------------------------------------------------------
{
if (!CheckAndStrip(ioWidgetIDString, "pref:"))
return PR_FALSE;
if (!CheckOrdinalAndStrip(ioWidgetIDString, outOrdinal))
return PR_FALSE;
if (CheckAndStrip(ioWidgetIDString, "bool:"))
{
outType = nsPrefWindow::eBool;
return PR_TRUE;
}
if (CheckAndStrip(ioWidgetIDString, "int:"))
{
outType = nsPrefWindow::eInt;
return PR_TRUE;
}
if (CheckAndStrip(ioWidgetIDString, "string:"))
{
outType = nsPrefWindow::eString;
return PR_TRUE;
}
if (CheckAndStrip(ioWidgetIDString, "path:"))
{
outType = nsPrefWindow::ePath;
return PR_TRUE;
}
return PR_FALSE;
} // ParseElementIDString
//----------------------------------------------------------------------------------------
nsresult nsPrefWindow::InitializeOneWidget(
nsIDOMHTMLInputElement* inElement,
const nsString& inWidgetType,
const char* inPrefName,
TypeOfPref inPrefType,
PRInt16 inPrefOrdinal)
//----------------------------------------------------------------------------------------
{
// See comments in FinalizeOneWidget for an explanation of the subtree technique. When
// initializing a widget, we have to check the subtree first, to see if the user has
// visited that panel previously and changed the value.
char tempPrefName[256];
PL_strcpy(tempPrefName, "temp_tree.");
PL_strcat(tempPrefName, inPrefName);
switch (inPrefType)
{
case eBool:
{
PRBool boolVal;
// Check the subtree first, then the real tree.
// If the preference value is not set at all, let the HTML
// determine the setting.
if (NS_SUCCEEDED(mPrefs->GetBoolPref(tempPrefName, &boolVal))
|| NS_SUCCEEDED(mPrefs->GetBoolPref(inPrefName, &boolVal)))
{
if (inWidgetType == "checkbox")
{
boolVal = (PRBool)(boolVal ^ inPrefOrdinal);
inElement->SetDefaultChecked(boolVal);
inElement->SetChecked(boolVal);
}
else if (inWidgetType == "radio" && inPrefOrdinal == boolVal)
{
// Radio pairs representing a boolean pref must have their
// ordinals "0" and "1". They work just like radio buttons
// representing int prefs.
// Turn on the radio whose ordinal matches the value.
// The others will turn off automatically.
inElement->SetDefaultChecked(PR_TRUE);
inElement->SetChecked(PR_TRUE);
}
}
break;
}
case eInt:
{
PRInt32 intVal;
// Check the subtree first, then the real tree.
// If the preference value is not set at all, let the HTML
// determine the setting.
if (NS_SUCCEEDED(mPrefs->GetIntPref(tempPrefName, &intVal))
|| NS_SUCCEEDED(mPrefs->GetIntPref(inPrefName, &intVal)))
{
if (inWidgetType == "radio")
{
// Turn on the radio whose ordinal matches the value.
// The others will turn off automatically.
if (inPrefOrdinal == intVal)
{
inElement->SetDefaultChecked(PR_TRUE);
inElement->SetChecked(PR_TRUE);
}
}
else if (inWidgetType == "text")
{
char charVal[32];
sprintf(charVal, "%d", (int)intVal);
nsString newValue(charVal);
inElement->SetValue(newValue);
}
}
break;
}
case eString:
{
// Check the subtree first, then the real tree.
// If the preference value is not set at all, let the HTML
// determine the setting.
char* charVal;
if (NS_SUCCEEDED(mPrefs->CopyCharPref(tempPrefName, &charVal))
|| NS_SUCCEEDED(mPrefs->CopyCharPref(inPrefName, &charVal)))
{
nsString newValue = charVal;
PR_Free(charVal);
inElement->SetValue(newValue);
}
break;
}
case ePath:
{
// Check the subtree first, then the real tree.
// If the preference value is not set at all, let the HTML
// determine the setting.
nsFileSpec *specVal;
nsresult rv = mPrefs->GetFilePref(tempPrefName, &specVal);
if (NS_FAILED(rv))
rv = mPrefs->GetFilePref(inPrefName, &specVal);
if NS_SUCCEEDED(rv) {
nsString newValue = specVal->GetCString();
inElement->SetValue(newValue);
delete specVal;
}
break;
}
}
return NS_OK;
} // nsPrefWindow::InitializeOneWidget
//----------------------------------------------------------------------------------------
nsresult nsPrefWindow::InitializeWidgetsRecursive(nsIDOMNode* inParentNode)
//----------------------------------------------------------------------------------------
{
if (!inParentNode)
return NS_OK;
PRBool hasChildren;
inParentNode->HasChildNodes(&hasChildren);
if (hasChildren)
{
//nsCOMPtr<nsIDOMNodeList> childList;
//inParentNode->GetChildNodes(getter_AddRefs(childList));
nsCOMPtr<nsIDOMNode> nextChild;
nsresult aResult = inParentNode->GetFirstChild(getter_AddRefs(nextChild));
while (NS_SUCCEEDED(aResult) && nextChild)
{
nsCOMPtr<nsIDOMNode> child = nextChild;
InitializeWidgetsRecursive(child);
aResult = child->GetNextSibling(getter_AddRefs(nextChild));
}
}
// OK, the buck stops here. Do the real work.
PRUint16 aNodeType;
nsresult rv = inParentNode->GetNodeType(&aNodeType);
if (NS_SUCCEEDED(rv) && aNodeType == nsIDOMNode::ELEMENT_NODE)
{
nsCOMPtr<nsIDOMHTMLInputElement> element = do_QueryInterface(inParentNode);
if (element)
{
nsString prefName;
TypeOfPref prefType;
PRInt16 ordinal;
element->GetId( prefName);
if (ParseElementIDString(prefName, prefType, ordinal))
{
nsString widgetType;
element->GetType(widgetType);
char* prefNameString = GetSubstitution(prefName);
InitializeOneWidget(element, widgetType, prefNameString,
prefType, ordinal);
PR_Free(prefNameString);
}
}
}
return NS_OK;
} // InitializeWidgetsRecursive
//----------------------------------------------------------------------------------------
nsresult nsPrefWindow::InitializePrefWidgets()
//----------------------------------------------------------------------------------------
{
NS_ASSERTION(mPanelWindow, "panel window is null");
NS_ASSERTION(mPrefs, "prefs pointer is null");
if (!mPanelWindow || !mPrefs)
return NS_ERROR_FAILURE;
nsCOMPtr<nsIDOMDocument> aDOMDoc;
mPanelWindow->GetDocument(getter_AddRefs(aDOMDoc));
return InitializeWidgetsRecursive(aDOMDoc);
} // nsPrefWindow::InitializePrefWidgets
//----------------------------------------------------------------------------------------
nsresult nsPrefWindow::FinalizeOneWidget(
nsIDOMHTMLInputElement* inElement,
const nsString& inWidgetType,
const char* inPrefName,
TypeOfPref inPrefType,
PRInt16 inPrefOrdinal)
//----------------------------------------------------------------------------------------
{
// As each panel is replaced, the values of its widgets are written out to a subtree
// of the prefs tree with root at "temp_tree". This subtree is rather sparse, since it
// only contains prefs (if any) that are represented by widgets in panels that the user
// visits. If the user clicks "OK" at the end, then prefs in this subtree will be
// copied back over to the real tree. This subtree will be deleted at the end
// in either case (OK or Cancel).
char tempPrefName[256];
PL_strcpy(tempPrefName, "temp_tree.");
PL_strcat(tempPrefName, inPrefName);
switch (inPrefType)
{
case eBool:
{
PRBool boolVal;
nsresult rv = inElement->GetChecked(&boolVal);
if (NS_FAILED(rv))
return rv;
if (inWidgetType == "checkbox")
{
boolVal = (PRBool)(boolVal ^ inPrefOrdinal);
mPrefs->SetBoolPref(tempPrefName, boolVal);
}
else if (inWidgetType == "radio" && boolVal)
{
// The radio that is ON writes out its ordinal. Others do nothing.
mPrefs->SetBoolPref(tempPrefName, inPrefOrdinal);
}
break;
}
case eInt:
{
if (inWidgetType == "radio")
{
// The radio that is ON writes out its ordinal. Others do nothing.
PRBool boolVal;
nsresult rv = inElement->GetChecked(&boolVal);
if (NS_FAILED(rv) || !boolVal)
return rv;
mPrefs->SetIntPref(tempPrefName, inPrefOrdinal);
}
else if (inWidgetType == "text")
{
nsString fieldValue;
nsresult rv = inElement->GetValue(fieldValue);
if (NS_FAILED(rv))
return rv;
char* s = fieldValue.ToNewCString();
mPrefs->SetIntPref(tempPrefName, atoi(s));
delete [] s;
}
break;
}
case eString:
{
nsString fieldValue;
nsresult rv = inElement->GetValue(fieldValue);
if (NS_FAILED(rv))
return rv;
char* s = fieldValue.ToNewCString();
mPrefs->SetCharPref(tempPrefName, s);
delete [] s;
break;
}
case ePath:
{
nsString fieldValue;
nsresult rv = inElement->GetValue(fieldValue);
if (NS_FAILED(rv))
return rv;
nsFileSpec specValue(fieldValue);
mPrefs->SetFilePref(tempPrefName, &specValue, PR_TRUE);
break;
}
}
// if (inWidgetType == "checkbox" || inWidgetType = "radio")
// {
// inElement->SetAttribute(attributeToSet, newValue);
// }
return NS_OK;
} // nsPrefWindow::FinalizeOneWidget
//----------------------------------------------------------------------------------------
nsresult nsPrefWindow::FinalizeWidgetsRecursive(nsIDOMNode* inParentNode)
//----------------------------------------------------------------------------------------
{
if (!inParentNode)
return NS_OK;
PRBool hasChildren;
inParentNode->HasChildNodes(&hasChildren);
if (hasChildren)
{
//nsCOMPtr<nsIDOMNodeList> childList;
//inParentNode->GetChildNodes(getter_AddRefs(childList));
nsCOMPtr<nsIDOMNode> nextChild;
nsresult aResult = inParentNode->GetFirstChild(getter_AddRefs(nextChild));
while (NS_SUCCEEDED(aResult) && nextChild)
{
nsCOMPtr<nsIDOMNode> child = nextChild;
FinalizeWidgetsRecursive(child);
aResult = child->GetNextSibling(getter_AddRefs(nextChild));
}
}
// OK, the buck stops here. Do the real work.
PRUint16 aNodeType;
nsresult rv = inParentNode->GetNodeType(&aNodeType);
if (NS_SUCCEEDED(rv) && aNodeType == nsIDOMNode::ELEMENT_NODE)
{
nsCOMPtr<nsIDOMHTMLInputElement> element = do_QueryInterface(inParentNode);
if (element)
{
nsString prefName;
TypeOfPref prefType;
PRInt16 ordinal;
element->GetId( prefName);
if (ParseElementIDString(prefName, prefType, ordinal))
{
nsString widgetType;
element->GetType(widgetType);
char* prefNameString = GetSubstitution(prefName);
FinalizeOneWidget(element, widgetType, prefNameString, prefType, ordinal);
delete [] prefNameString;
}
}
}
return NS_OK;
} // FinalizeWidgetsRecursive
//----------------------------------------------------------------------------------------
nsresult nsPrefWindow::FinalizePrefWidgets()
//----------------------------------------------------------------------------------------
{
NS_ASSERTION(mPanelWindow, "panel window is null");
NS_ASSERTION(mPrefs, "prefs pointer is null");
if (!mPanelWindow || !mPrefs)
return NS_ERROR_FAILURE;
nsCOMPtr<nsIDOMDocument> aDOMDoc;
mPanelWindow->GetDocument(getter_AddRefs(aDOMDoc));
return FinalizeWidgetsRecursive(aDOMDoc);
} // nsPrefWindow::FinalizePrefWidgets
//----------------------------------------------------------------------------------------
NS_IMETHODIMP nsPrefWindow::ShowWindow(nsIDOMWindow* aCurrentFrontWin)
//----------------------------------------------------------------------------------------
{
// (code adapted from nsToolkitCore::ShowModal. yeesh.)
nsresult rv;
nsIWebShellWindow *window;
window = nsnull;
nsCOMPtr<nsIURL> urlObj;
rv = NS_NewURL(getter_AddRefs(urlObj), "resource://res/samples/PrefsWindow.html");
if (NS_FAILED(rv))
return rv;
NS_WITH_SERVICE(nsIAppShellService, appShell, kAppShellServiceCID, &rv);
if (NS_FAILED(rv))
return rv;
// Create "save to disk" nsIXULCallbacks...
//nsIXULWindowCallbacks *cb = new nsFindDialogCallbacks( aURL, aContentType );
nsIXULWindowCallbacks *cb = nsnull;
nsCOMPtr<nsIWebShellWindow> parent;
DOMWindowToWebShellWindow(aCurrentFrontWin, &parent);
appShell->CreateDialogWindow(parent, urlObj, PR_TRUE, window,
nsnull, cb, 504, 436);
if (window != nsnull) {
nsCOMPtr<nsIWidget> parentWindowWidgetThing;
nsresult gotParent;
gotParent = parent ? parent->GetWidget(*getter_AddRefs(parentWindowWidgetThing)) :
NS_ERROR_FAILURE;
// Windows OS is the only one that needs the parent disabled, or cares
// arguably this should be done by the new window, within ShowModal...
if (NS_SUCCEEDED(gotParent))
parentWindowWidgetThing->Enable(PR_FALSE);
window->ShowModal();
if (NS_SUCCEEDED(gotParent))
parentWindowWidgetThing->Enable(PR_TRUE);
}
return rv;
} // nsPrefWindow::ShowWindow
//----------------------------------------------------------------------------------------
NS_IMETHODIMP nsPrefWindow::ChangePanel(const PRUnichar* aURL)
// Start loading of a new prefs panel.
//----------------------------------------------------------------------------------------
{
NS_ASSERTION(mPanelWindow, "panel window is null");
if (!mPanelWindow)
return NS_OK;
nsresult rv = FinalizePrefWidgets();
if (NS_FAILED(rv))
return rv;
nsCOMPtr<nsIScriptGlobalObject> globalScript(do_QueryInterface(mPanelWindow));
if (!globalScript)
return NS_ERROR_FAILURE;
nsCOMPtr<nsIWebShell> webshell;
globalScript->GetWebShell(getter_AddRefs(webshell));
if (!webshell)
return NS_ERROR_FAILURE;
webshell->LoadURL(aURL);
return NS_OK;
}
//----------------------------------------------------------------------------------------
NS_IMETHODIMP nsPrefWindow::PanelLoaded(nsIDOMWindow* aWin)
// Callback after loading of a new prefs panel.
//----------------------------------------------------------------------------------------
{
// Out with the old!
if (mPanelWindow != aWin)
{
NS_IF_RELEASE(mPanelWindow);
mPanelWindow = aWin;
NS_IF_ADDREF(mPanelWindow);
}
// In with the new!
if (mPanelWindow)
{
nsresult rv = InitializePrefWidgets();
if (NS_FAILED(rv))
return rv;
}
return NS_OK;
}
//----------------------------------------------------------------------------------------
static void DOMWindowToWebShellWindow(
nsIDOMWindow *DOMWindow,
nsCOMPtr<nsIWebShellWindow> *webWindow)
//----------------------------------------------------------------------------------------
{
if (!DOMWindow)
return; // with webWindow unchanged -- its constructor gives it a null ptr
nsCOMPtr<nsIScriptGlobalObject> globalScript(do_QueryInterface(DOMWindow));
nsCOMPtr<nsIWebShell> webshell, rootWebshell;
if (globalScript)
globalScript->GetWebShell(getter_AddRefs(webshell));
if (webshell)
webshell->GetRootWebShellEvenIfChrome(*getter_AddRefs(rootWebshell));
if (rootWebshell) {
nsCOMPtr<nsIWebShellContainer> webshellContainer;
rootWebshell->GetContainer(*getter_AddRefs(webshellContainer));
*webWindow = do_QueryInterface(webshellContainer);
}
}
//----------------------------------------------------------------------------------------
static nsresult Close(nsIDOMWindow*& dw)
//----------------------------------------------------------------------------------------
{
if (!dw)
return NS_ERROR_FAILURE;
nsIDOMWindow* top;
dw->GetTop(&top);
if (!top)
return NS_ERROR_FAILURE;
nsCOMPtr<nsIWebShellWindow> parent;
DOMWindowToWebShellWindow(top, &parent);
if (parent)
parent->Close();
NS_IF_RELEASE(dw);
return NS_OK;
}
//----------------------------------------------------------------------------------------
NS_IMETHODIMP nsPrefWindow::SavePrefs()
//----------------------------------------------------------------------------------------
{
FinalizePrefWidgets();
if (mPrefs)
{
// Do the prefs stuff...
mPrefs->CopyPrefsTree("temp_tree", "");
mPrefs->DeleteBranch("temp_tree");
mPrefs->SavePrefFile();
}
// Then close
return Close(mPanelWindow);
} // nsPrefWindow::SavePrefs
//----------------------------------------------------------------------------------------
char* nsPrefWindow::GetSubstitution(nsString& formatstr)
//----------------------------------------------------------------------------------------
{
#define substring(_i) mSubStrings[_i] ? mSubStrings[_i] : ""
char *cformatstr = formatstr.ToNewCString();
// for now use PR_smprintf and hardcode the strings as parameters
char* result = PR_smprintf(
cformatstr,
substring(0),
substring(1),
substring(2),
substring(3),
substring(4),
substring(5),
substring(6),
substring(7),
substring(8),
substring(9));
delete[] cformatstr;
return result;
} // nsPrefWindow::GetSubstitution
//----------------------------------------------------------------------------------------
NS_IMETHODIMP nsPrefWindow::CancelPrefs()
//----------------------------------------------------------------------------------------
{
// Do the prefs stuff...
if (mPrefs)
mPrefs->DeleteBranch("temp_tree");
// Then close
return Close(mPanelWindow);
}
//----------------------------------------------------------------------------------------
NS_IMETHODIMP nsPrefWindow::SetSubstitutionVar(
PRUint32 aStringnum,
const char* aVal)
//----------------------------------------------------------------------------------------
{
if (aStringnum < PREFWINDOW_MAX_STRINGS)
{
NS_WARNING("substitution string number to large");
return NS_ERROR_UNEXPECTED;
}
if (mSubStrings[aStringnum])
delete[] mSubStrings[aStringnum];
nsString s(aVal);
mSubStrings[aStringnum] = s.ToNewCString();
return NS_OK;
} // nsPrefWindow::SetSubstitutionVar