Back to index

lightning-sunbird  0.9+nobinonly
nsWindowDataSource.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 200
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #include "nsWindowDataSource.h"
00039 #include "nsIXULWindow.h"
00040 #include "rdf.h"
00041 #include "nsIRDFContainerUtils.h"
00042 #include "nsIServiceManager.h"
00043 #include "nsReadableUtils.h"
00044 #include "nsObserverService.h"
00045 #include "nsIWindowMediator.h"
00046 
00047 // just to do the reverse-lookup! sheesh.
00048 #include "nsIInterfaceRequestorUtils.h"
00049 #include "nsIDocShell.h"
00050 
00051 PRUint32 nsWindowDataSource::windowCount = 0;
00052 
00053 nsIRDFResource* nsWindowDataSource::kNC_Name = nsnull;
00054 nsIRDFResource* nsWindowDataSource::kNC_WindowRoot = nsnull;
00055 nsIRDFResource* nsWindowDataSource::kNC_KeyIndex = nsnull;
00056 
00057 nsIRDFService*  nsWindowDataSource::gRDFService = nsnull;
00058 
00059 PRUint32 nsWindowDataSource::gRefCnt = 0;
00060 
00061 static const char kURINC_WindowRoot[] = "NC:WindowMediatorRoot";
00062 
00063 DEFINE_RDF_VOCAB(NC_NAMESPACE_URI, NC, Name);
00064 DEFINE_RDF_VOCAB(NC_NAMESPACE_URI, NC, KeyIndex);
00065 
00066 nsresult
00067 nsWindowDataSource::Init()
00068 {
00069     nsresult rv;
00070 
00071     if (gRefCnt++ == 0) {
00072         rv = CallGetService("@mozilla.org/rdf/rdf-service;1", &gRDFService);
00073         if (NS_FAILED(rv)) return rv;
00074 
00075         gRDFService->GetResource(NS_LITERAL_CSTRING(kURINC_WindowRoot), &kNC_WindowRoot);
00076         gRDFService->GetResource(NS_LITERAL_CSTRING(kURINC_Name),       &kNC_Name);
00077         gRDFService->GetResource(NS_LITERAL_CSTRING(kURINC_KeyIndex),   &kNC_KeyIndex);
00078     }
00079 
00080     mInner = do_CreateInstance("@mozilla.org/rdf/datasource;1?name=in-memory-datasource", &rv);
00081     if (NS_FAILED(rv)) return rv;
00082 
00083     nsCOMPtr<nsIRDFContainerUtils> rdfc =
00084         do_GetService("@mozilla.org/rdf/container-utils;1", &rv);
00085     if (NS_FAILED(rv)) return rv;
00086 
00087     rv = rdfc->MakeSeq(this, kNC_WindowRoot, getter_AddRefs(mContainer));
00088     if (NS_FAILED(rv)) return rv;
00089 
00090     nsCOMPtr<nsIWindowMediator> windowMediator =
00091         do_GetService(NS_WINDOWMEDIATOR_CONTRACTID, &rv);
00092     if (NS_FAILED(rv)) return rv;
00093 
00094     rv = windowMediator->AddListener(this);
00095     if (NS_FAILED(rv)) return rv;
00096 
00097     nsCOMPtr<nsIObserverService> observerService =
00098         do_GetService(NS_OBSERVERSERVICE_CONTRACTID, &rv);
00099     if (NS_SUCCEEDED(rv)) {
00100         rv = observerService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID,
00101                                           PR_FALSE);
00102     }
00103     return NS_OK;
00104 }
00105 
00106 nsWindowDataSource::~nsWindowDataSource()
00107 {
00108     if (--gRefCnt == 0) {
00109         NS_IF_RELEASE(kNC_Name);
00110         NS_IF_RELEASE(kNC_KeyIndex);
00111         NS_IF_RELEASE(kNC_WindowRoot);
00112         NS_IF_RELEASE(gRDFService);
00113     }
00114 }
00115 
00116 NS_IMETHODIMP
00117 nsWindowDataSource::Observe(nsISupports *aSubject, const char* aTopic, const PRUnichar *aData)
00118 {
00119     if (strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) {
00120         // release these objects so that they release their reference
00121         // to us
00122         mContainer = nsnull;
00123         mInner = nsnull;
00124     }
00125 
00126     return NS_OK;
00127 }
00128 
00129 #if 0
00130 NS_IMETHODIMP_(nsrefcnt)
00131 nsWindowMediator::Release()
00132 {
00133        // We need a special implementation of Release() due to having
00134        // two circular references:  mInner and mContainer
00135 
00136        NS_PRECONDITION(PRInt32(mRefCnt) > 0, "duplicate release");
00137        --mRefCnt;
00138        NS_LOG_RELEASE(this, mRefCnt, "nsWindowMediator");
00139 
00140        if (mInner && mRefCnt == 2)
00141        {
00142               NS_IF_RELEASE(mContainer);
00143               mContainer = nsnull;
00144 
00145               nsIRDFDataSource* tmp = mInner;
00146               mInner = nsnull;
00147               NS_IF_RELEASE(tmp);
00148               return(0);
00149        }
00150        else if (mRefCnt == 0)
00151        {
00152               mRefCnt = 1;
00153               delete this;
00154               return(0);
00155        }
00156        return(mRefCnt);
00157 }
00158 
00159 #endif
00160 
00161 
00162 NS_IMPL_ISUPPORTS4(nsWindowDataSource,
00163                    nsIObserver,
00164                    nsIWindowMediatorListener,
00165                    nsIWindowDataSource,
00166                    nsIRDFDataSource)
00167 
00168 // nsIWindowMediatorListener implementation
00169 // handle notifications from the window mediator and reflect them into
00170 // RDF
00171 
00172 /* void onWindowTitleChange (in nsIXULWindow window, in wstring newTitle); */
00173 NS_IMETHODIMP
00174 nsWindowDataSource::OnWindowTitleChange(nsIXULWindow *window,
00175                                         const PRUnichar *newTitle)
00176 {
00177     nsresult rv;
00178     
00179     nsVoidKey key(window);
00180 
00181     nsCOMPtr<nsISupports> sup =
00182         dont_AddRef(mWindowResources.Get(&key));
00183 
00184     // oops, make sure this window is in the hashtable!
00185     if (!sup) {
00186         OnOpenWindow(window);
00187         sup = dont_AddRef(mWindowResources.Get(&key));
00188     }
00189     
00190     NS_ENSURE_TRUE(sup, NS_ERROR_UNEXPECTED);
00191 
00192     nsCOMPtr<nsIRDFResource> windowResource =
00193         do_QueryInterface(sup);
00194 
00195     nsCOMPtr<nsIRDFLiteral> newTitleLiteral;
00196     rv = gRDFService->GetLiteral(newTitle, getter_AddRefs(newTitleLiteral));
00197     NS_ENSURE_SUCCESS(rv, rv);
00198 
00199     // get the old title
00200     nsCOMPtr<nsIRDFNode> oldTitleNode;
00201     rv = GetTarget(windowResource, kNC_Name, PR_TRUE,
00202                    getter_AddRefs(oldTitleNode));
00203     
00204     // assert the change
00205     if (NS_SUCCEEDED(rv) && oldTitleNode)
00206         // has an existing window title, update it
00207         rv = Change(windowResource, kNC_Name, oldTitleNode, newTitleLiteral);
00208     else
00209         // removed from the tasklist
00210         rv = Assert(windowResource, kNC_Name, newTitleLiteral, PR_TRUE);
00211 
00212     if (rv != NS_RDF_ASSERTION_ACCEPTED)
00213     {
00214       NS_ERROR("unable to set window name");
00215     }
00216     
00217     return NS_OK;
00218 }
00219 
00220 /* void onOpenWindow (in nsIXULWindow window); */
00221 NS_IMETHODIMP
00222 nsWindowDataSource::OnOpenWindow(nsIXULWindow *window)
00223 {
00224     nsCAutoString windowId(NS_LITERAL_CSTRING("window-"));
00225     windowId.AppendInt(windowCount++, 10);
00226 
00227     nsCOMPtr<nsIRDFResource> windowResource;
00228     gRDFService->GetResource(windowId, getter_AddRefs(windowResource));
00229 
00230     nsVoidKey key(window);
00231     mWindowResources.Put(&key, windowResource);
00232 
00233     // assert the new window
00234     if (mContainer)
00235         mContainer->AppendElement(windowResource);
00236 
00237     return NS_OK;
00238 }
00239 
00240 /* void onCloseWindow (in nsIXULWindow window); */
00241 NS_IMETHODIMP
00242 nsWindowDataSource::OnCloseWindow(nsIXULWindow *window)
00243 {
00244     nsVoidKey key(window);
00245     nsCOMPtr<nsIRDFResource> resource;
00246 
00247     nsresult rv;
00248 
00249     if (!mWindowResources.Remove(&key, getter_AddRefs(resource)))
00250         return NS_ERROR_UNEXPECTED;
00251 
00252     // make sure we're not shutting down
00253     if (!mContainer) return NS_OK;
00254     
00255     nsCOMPtr<nsIRDFNode> oldKeyNode;
00256     nsCOMPtr<nsIRDFInt> oldKeyInt;
00257     
00258     // get the old keyIndex, if any
00259     rv = GetTarget(resource, kNC_KeyIndex, PR_TRUE,
00260                    getter_AddRefs(oldKeyNode));
00261     if (NS_SUCCEEDED(rv) && (rv != NS_RDF_NO_VALUE))
00262         oldKeyInt = do_QueryInterface(oldKeyNode);
00263 
00264     
00265     // update RDF and keyindex - from this point forward we'll ignore
00266     // errors, because they just indicate some kind of RDF inconsistency
00267     PRInt32 winIndex = -1;
00268     rv = mContainer->IndexOf(resource, &winIndex);
00269         
00270     if (NS_FAILED(rv))
00271         return NS_OK;
00272             
00273     // unassert the old window, ignore any error
00274     mContainer->RemoveElement(resource, PR_TRUE);
00275     
00276     nsCOMPtr<nsISimpleEnumerator> children;
00277     rv = mContainer->GetElements(getter_AddRefs(children));
00278     if (NS_FAILED(rv))
00279         return NS_OK;
00280 
00281     PRBool more = PR_FALSE;
00282 
00283     while (NS_SUCCEEDED(rv = children->HasMoreElements(&more)) && more) {
00284         nsCOMPtr<nsISupports> sup;
00285         rv = children->GetNext(getter_AddRefs(sup));
00286         if (NS_FAILED(rv))
00287             break;
00288 
00289         nsCOMPtr<nsIRDFResource> windowResource = do_QueryInterface(sup, &rv);
00290         if (NS_FAILED(rv))
00291             continue;
00292 
00293         PRInt32 currentIndex = -1;
00294         mContainer->IndexOf(windowResource, &currentIndex);
00295 
00296         // can skip updating windows with lower indexes
00297         // than the window that was removed
00298         if (currentIndex < winIndex)
00299             continue;
00300 
00301         nsCOMPtr<nsIRDFNode> newKeyNode;
00302         nsCOMPtr<nsIRDFInt> newKeyInt;
00303 
00304         rv = GetTarget(windowResource, kNC_KeyIndex, PR_TRUE,
00305                        getter_AddRefs(newKeyNode));
00306         if (NS_SUCCEEDED(rv) && (rv != NS_RDF_NO_VALUE))
00307             newKeyInt = do_QueryInterface(newKeyNode);
00308 
00309         // changing from one key index to another
00310         if (oldKeyInt && newKeyInt)
00311             Change(windowResource, kNC_KeyIndex, oldKeyInt, newKeyInt);
00312         // creating a new keyindex - probably window going
00313         // from (none) to "9"
00314         else if (newKeyInt)
00315             Assert(windowResource, kNC_KeyIndex, newKeyInt, PR_TRUE);
00316         
00317         // somehow inserting a window above this one,
00318         // "9" to (none)
00319         else if (oldKeyInt)
00320             Unassert(windowResource, kNC_KeyIndex, oldKeyInt);
00321         
00322     }
00323     return NS_OK;
00324 }
00325 
00326 struct findWindowClosure {
00327     nsIRDFResource* targetResource;
00328     nsIXULWindow *resultWindow;
00329 };
00330 
00331 PR_STATIC_CALLBACK(PRBool)
00332 findWindow(nsHashKey* aKey, void *aData, void* aClosure)
00333 {
00334     nsVoidKey *thisKey = NS_STATIC_CAST(nsVoidKey*, aKey);
00335 
00336     nsIRDFResource *resource =
00337         NS_STATIC_CAST(nsIRDFResource*, aData);
00338     
00339     findWindowClosure* closure =
00340         NS_STATIC_CAST(findWindowClosure*, aClosure);
00341 
00342     if (resource == closure->targetResource) {
00343         closure->resultWindow =
00344             NS_STATIC_CAST(nsIXULWindow*,
00345                            thisKey->GetValue());
00346         return PR_FALSE;         // stop enumerating
00347     }
00348     return PR_TRUE;
00349 }
00350 
00351 // nsIWindowDataSource implementation
00352 
00353 NS_IMETHODIMP
00354 nsWindowDataSource::GetWindowForResource(const char *aResourceString,
00355                                          nsIDOMWindowInternal** aResult)
00356 {
00357     nsCOMPtr<nsIRDFResource> windowResource;
00358     gRDFService->GetResource(nsDependentCString(aResourceString),
00359                              getter_AddRefs(windowResource));
00360 
00361     // now reverse-lookup in the hashtable
00362     findWindowClosure closure = { windowResource.get(), nsnull };
00363     mWindowResources.Enumerate(findWindow, (void*)&closure);
00364     if (closure.resultWindow) {
00365 
00366         // this sucks, we have to jump through docshell to go from
00367         // nsIXULWindow -> nsIDOMWindowInternal
00368         nsCOMPtr<nsIDocShell> docShell;
00369         closure.resultWindow->GetDocShell(getter_AddRefs(docShell));
00370 
00371         if (docShell) {
00372             nsCOMPtr<nsIDOMWindowInternal> result =
00373                 do_GetInterface(docShell);
00374         
00375             *aResult = result;
00376             NS_IF_ADDREF(*aResult);
00377         }
00378     }
00379 
00380     return NS_OK;
00381 }
00382 
00383 
00384 // nsIRDFDataSource implementation
00385 // mostly, we just forward to mInner, except:
00386 // GetURI() - need to return "rdf:window-mediator"
00387 // GetTarget() - need to handle kNC_KeyIndex
00388 
00389 
00390 /* readonly attribute string URI; */
00391 NS_IMETHODIMP nsWindowDataSource::GetURI(char * *aURI)
00392 {
00393     NS_ENSURE_ARG_POINTER(aURI);
00394     
00395     *aURI = ToNewCString(NS_LITERAL_CSTRING("rdf:window-mediator"));
00396 
00397     if (!*aURI)
00398         return NS_ERROR_OUT_OF_MEMORY;
00399     
00400     return NS_OK;
00401 }
00402 
00403 /* nsIRDFNode GetTarget (in nsIRDFResource aSource, in nsIRDFResource aProperty, in boolean aTruthValue); */
00404 NS_IMETHODIMP nsWindowDataSource::GetTarget(nsIRDFResource *aSource, nsIRDFResource *aProperty, PRBool aTruthValue, nsIRDFNode **_retval)
00405 {
00406     NS_ENSURE_ARG_POINTER(_retval);
00407 
00408     // add extra NULL checking for top-crash bug # 146466
00409     if (!gRDFService) return NS_RDF_NO_VALUE;
00410     if (!mInner) return NS_RDF_NO_VALUE;
00411     if (!mContainer) return NS_RDF_NO_VALUE;
00412     // special case kNC_KeyIndex before we forward to mInner
00413     if (aProperty == kNC_KeyIndex) {
00414 
00415         PRInt32 theIndex = 0;
00416         nsresult rv = mContainer->IndexOf(aSource, &theIndex);
00417         if (NS_FAILED(rv)) return rv;
00418 
00419         // only allow the range of 1 to 9 for single key access
00420         if (theIndex < 1 || theIndex > 9) return(NS_RDF_NO_VALUE);
00421 
00422         nsCOMPtr<nsIRDFInt> indexInt;
00423         rv = gRDFService->GetIntLiteral(theIndex, getter_AddRefs(indexInt));
00424         if (NS_FAILED(rv)) return(rv);
00425         if (!indexInt) return(NS_ERROR_FAILURE);
00426         
00427         return CallQueryInterface(indexInt, _retval);
00428     }
00429 
00430     
00431     return mInner->GetTarget(aSource, aProperty, aTruthValue, _retval);
00432 }
00433 
00434 /* nsIRDFResource GetSource (in nsIRDFResource aProperty, in nsIRDFNode aTarget, in boolean aTruthValue); */
00435 NS_IMETHODIMP nsWindowDataSource::GetSource(nsIRDFResource *aProperty, nsIRDFNode *aTarget, PRBool aTruthValue, nsIRDFResource **_retval)
00436 {
00437     if (mInner)
00438         return mInner->GetSource(aProperty, aTarget, aTruthValue, _retval);
00439     return NS_OK;
00440 }
00441 
00442 /* nsISimpleEnumerator GetSources (in nsIRDFResource aProperty, in nsIRDFNode aTarget, in boolean aTruthValue); */
00443 NS_IMETHODIMP nsWindowDataSource::GetSources(nsIRDFResource *aProperty, nsIRDFNode *aTarget, PRBool aTruthValue, nsISimpleEnumerator **_retval)
00444 {
00445     if (mInner)
00446         return mInner->GetSources(aProperty, aTarget, aTruthValue, _retval);
00447     return NS_OK;
00448 }
00449 
00450 /* nsISimpleEnumerator GetTargets (in nsIRDFResource aSource, in nsIRDFResource aProperty, in boolean aTruthValue); */
00451 NS_IMETHODIMP nsWindowDataSource::GetTargets(nsIRDFResource *aSource, nsIRDFResource *aProperty, PRBool aTruthValue, nsISimpleEnumerator **_retval)
00452 {
00453     if (mInner)
00454         return mInner->GetTargets(aSource, aProperty, aTruthValue, _retval);
00455     return NS_OK;
00456 }
00457 
00458 /* void Assert (in nsIRDFResource aSource, in nsIRDFResource aProperty, in nsIRDFNode aTarget, in boolean aTruthValue); */
00459 NS_IMETHODIMP nsWindowDataSource::Assert(nsIRDFResource *aSource, nsIRDFResource *aProperty, nsIRDFNode *aTarget, PRBool aTruthValue)
00460 {
00461     if (mInner)
00462         return mInner->Assert(aSource, aProperty, aTarget, aTruthValue);
00463     return NS_OK;
00464 }
00465 
00466 /* void Unassert (in nsIRDFResource aSource, in nsIRDFResource aProperty, in nsIRDFNode aTarget); */
00467 NS_IMETHODIMP nsWindowDataSource::Unassert(nsIRDFResource *aSource, nsIRDFResource *aProperty, nsIRDFNode *aTarget)
00468 {
00469     if (mInner)
00470         return mInner->Unassert(aSource, aProperty, aTarget);
00471     return NS_OK;
00472 }
00473 
00474 /* void Change (in nsIRDFResource aSource, in nsIRDFResource aProperty, in nsIRDFNode aOldTarget, in nsIRDFNode aNewTarget); */
00475 NS_IMETHODIMP nsWindowDataSource::Change(nsIRDFResource *aSource, nsIRDFResource *aProperty, nsIRDFNode *aOldTarget, nsIRDFNode *aNewTarget)
00476 {
00477     if (mInner)
00478         return mInner->Change(aSource, aProperty, aOldTarget, aNewTarget);
00479     return NS_OK;
00480 }
00481 
00482 /* void Move (in nsIRDFResource aOldSource, in nsIRDFResource aNewSource, in nsIRDFResource aProperty, in nsIRDFNode aTarget); */
00483 NS_IMETHODIMP nsWindowDataSource::Move(nsIRDFResource *aOldSource, nsIRDFResource *aNewSource, nsIRDFResource *aProperty, nsIRDFNode *aTarget)
00484 {
00485     if (mInner)
00486         return mInner->Move(aOldSource, aNewSource, aProperty, aTarget);
00487     return NS_OK;
00488 }
00489 
00490 /* boolean HasAssertion (in nsIRDFResource aSource, in nsIRDFResource aProperty, in nsIRDFNode aTarget, in boolean aTruthValue); */
00491 NS_IMETHODIMP nsWindowDataSource::HasAssertion(nsIRDFResource *aSource, nsIRDFResource *aProperty, nsIRDFNode *aTarget, PRBool aTruthValue, PRBool *_retval)
00492 {
00493     if (mInner)
00494         return mInner->HasAssertion(aSource, aProperty, aTarget, aTruthValue, _retval);
00495     return NS_OK;
00496 }
00497 
00498 /* void AddObserver (in nsIRDFObserver aObserver); */
00499 NS_IMETHODIMP nsWindowDataSource::AddObserver(nsIRDFObserver *aObserver)
00500 {
00501     if (mInner)
00502         return mInner->AddObserver(aObserver);
00503     return NS_OK;
00504 }
00505 
00506 /* void RemoveObserver (in nsIRDFObserver aObserver); */
00507 NS_IMETHODIMP nsWindowDataSource::RemoveObserver(nsIRDFObserver *aObserver)
00508 {
00509     if (mInner)
00510         return mInner->RemoveObserver(aObserver);
00511     return NS_OK;
00512 }
00513 
00514 /* nsISimpleEnumerator ArcLabelsIn (in nsIRDFNode aNode); */
00515 NS_IMETHODIMP nsWindowDataSource::ArcLabelsIn(nsIRDFNode *aNode, nsISimpleEnumerator **_retval)
00516 {
00517     if (mInner)
00518         return mInner->ArcLabelsIn(aNode, _retval);
00519     return NS_OK;
00520 }
00521 
00522 /* nsISimpleEnumerator ArcLabelsOut (in nsIRDFResource aSource); */
00523 NS_IMETHODIMP nsWindowDataSource::ArcLabelsOut(nsIRDFResource *aSource, nsISimpleEnumerator **_retval)
00524 {
00525     if (mInner)
00526         return mInner->ArcLabelsOut(aSource, _retval);
00527     return NS_OK;
00528 }
00529 
00530 /* nsISimpleEnumerator GetAllResources (); */
00531 NS_IMETHODIMP nsWindowDataSource::GetAllResources(nsISimpleEnumerator **_retval)
00532 {
00533     if (mInner)
00534         return mInner->GetAllResources(_retval);
00535     return NS_OK;
00536 }
00537 
00538 /* boolean IsCommandEnabled (in nsISupportsArray aSources, in nsIRDFResource aCommand, in nsISupportsArray aArguments); */
00539 NS_IMETHODIMP nsWindowDataSource::IsCommandEnabled(nsISupportsArray *aSources, nsIRDFResource *aCommand, nsISupportsArray *aArguments, PRBool *_retval)
00540 {
00541     if (mInner)
00542         return mInner->IsCommandEnabled(aSources, aCommand, aArguments, _retval);
00543     return NS_OK;
00544 }
00545 
00546 /* void DoCommand (in nsISupportsArray aSources, in nsIRDFResource aCommand, in nsISupportsArray aArguments); */
00547 NS_IMETHODIMP nsWindowDataSource::DoCommand(nsISupportsArray *aSources, nsIRDFResource *aCommand, nsISupportsArray *aArguments)
00548 {
00549     if (mInner)
00550         return mInner->DoCommand(aSources, aCommand, aArguments);
00551     return NS_OK;
00552 }
00553 
00554 /* nsISimpleEnumerator GetAllCmds (in nsIRDFResource aSource); */
00555 NS_IMETHODIMP nsWindowDataSource::GetAllCmds(nsIRDFResource *aSource, nsISimpleEnumerator **_retval)
00556 {
00557     if (mInner)
00558         return mInner->GetAllCmds(aSource, _retval);
00559     return NS_OK;
00560 }
00561 
00562 /* boolean hasArcIn (in nsIRDFNode aNode, in nsIRDFResource aArc); */
00563 NS_IMETHODIMP nsWindowDataSource::HasArcIn(nsIRDFNode *aNode, nsIRDFResource *aArc, PRBool *_retval)
00564 {
00565     if (mInner)
00566         return mInner->HasArcIn(aNode, aArc, _retval);
00567     return NS_OK;
00568 }
00569 
00570 /* boolean hasArcOut (in nsIRDFResource aSource, in nsIRDFResource aArc); */
00571 NS_IMETHODIMP nsWindowDataSource::HasArcOut(nsIRDFResource *aSource, nsIRDFResource *aArc, PRBool *_retval)
00572 {
00573     if (mInner)
00574         return mInner->HasArcOut(aSource, aArc, _retval);
00575     return NS_OK;
00576 }
00577 
00578 /* void beginUpdateBatch (); */
00579 NS_IMETHODIMP nsWindowDataSource::BeginUpdateBatch()
00580 {
00581     if (mInner)
00582         return mInner->BeginUpdateBatch();
00583     return NS_OK;
00584 }
00585                                                                                 
00586 /* void endUpdateBatch (); */
00587 NS_IMETHODIMP nsWindowDataSource::EndUpdateBatch()
00588 {
00589     if (mInner)
00590         return mInner->EndUpdateBatch();
00591     return NS_OK;
00592 }