Back to index

lightning-sunbird  0.9+nobinonly
nsDocShellEnumerator.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
00002  *
00003  * ***** BEGIN LICENSE BLOCK *****
00004  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00005  *
00006  * The contents of this file are subject to the Mozilla Public License Version
00007  * 1.1 (the "License"); you may not use this file except in compliance with
00008  * the License. You may obtain a copy of the License at
00009  * http://www.mozilla.org/MPL/
00010  *
00011  * Software distributed under the License is distributed on an "AS IS" basis,
00012  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00013  * for the specific language governing rights and limitations under the
00014  * License.
00015  *
00016  * The Original Code is the Mozilla browser.
00017  *
00018  * The Initial Developer of the Original Code is
00019  * Netscape Communications, Inc.
00020  * Portions created by the Initial Developer are Copyright (C) 1999
00021  * the Initial Developer. All Rights Reserved.
00022  *
00023  * Contributor(s):
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either of the GNU General Public License Version 2 or later (the "GPL"),
00027  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 
00040 #include "nsDocShellEnumerator.h"
00041 
00042 #include "nsIDocShellTreeNode.h"
00043 
00044 nsDocShellEnumerator::nsDocShellEnumerator(PRInt32 inEnumerationDirection)
00045 : mRootItem(nsnull)
00046 , mItemArray(nsnull)
00047 , mCurIndex(0)
00048 , mDocShellType(nsIDocShellTreeItem::typeAll)
00049 , mEnumerationDirection(inEnumerationDirection)
00050 {
00051 }
00052 
00053 nsDocShellEnumerator::~nsDocShellEnumerator()
00054 {
00055   delete mItemArray;
00056 }
00057 
00058 NS_IMPL_ISUPPORTS1(nsDocShellEnumerator, nsISimpleEnumerator)
00059 
00060 
00061 /* nsISupports getNext (); */
00062 NS_IMETHODIMP nsDocShellEnumerator::GetNext(nsISupports **outCurItem)
00063 {
00064   NS_ENSURE_ARG_POINTER(outCurItem);
00065   *outCurItem = nsnull;
00066   
00067   nsresult rv = EnsureDocShellArray();
00068   if (NS_FAILED(rv)) return rv;
00069   
00070   if (mCurIndex >= 0 && mCurIndex < mItemArray->Count())
00071   {
00072     nsIDocShellTreeItem* thisItem = NS_REINTERPRET_CAST(nsIDocShellTreeItem*, mItemArray->ElementAt(mCurIndex));
00073     rv = thisItem->QueryInterface(NS_GET_IID(nsISupports), (void **)outCurItem);
00074     if (NS_FAILED(rv)) return rv;
00075   }
00076   else
00077     return NS_ERROR_FAILURE;
00078   
00079   mCurIndex ++;
00080   
00081   return NS_OK;
00082 }
00083 
00084 /* boolean hasMoreElements (); */
00085 NS_IMETHODIMP nsDocShellEnumerator::HasMoreElements(PRBool *outHasMore)
00086 {
00087   NS_ENSURE_ARG_POINTER(outHasMore);
00088   *outHasMore = PR_FALSE;
00089 
00090   nsresult rv = EnsureDocShellArray();
00091   if (NS_FAILED(rv)) return rv;
00092 
00093   *outHasMore = (mCurIndex < mItemArray->Count());
00094   return NS_OK;
00095 }
00096 
00097 nsresult nsDocShellEnumerator::GetEnumerationRootItem(nsIDocShellTreeItem * *aEnumerationRootItem)
00098 {
00099   NS_ENSURE_ARG_POINTER(aEnumerationRootItem);
00100   *aEnumerationRootItem = mRootItem;
00101   NS_IF_ADDREF(*aEnumerationRootItem);
00102   return NS_OK;
00103 }
00104 
00105 nsresult nsDocShellEnumerator::SetEnumerationRootItem(nsIDocShellTreeItem * aEnumerationRootItem)
00106 {
00107   mRootItem = aEnumerationRootItem;
00108   ClearState();
00109   return NS_OK;
00110 }
00111 
00112 nsresult nsDocShellEnumerator::GetEnumDocShellType(PRInt32 *aEnumerationItemType)
00113 {
00114   NS_ENSURE_ARG_POINTER(aEnumerationItemType);
00115   *aEnumerationItemType = mDocShellType;
00116   return NS_OK;
00117 }
00118 
00119 nsresult nsDocShellEnumerator::SetEnumDocShellType(PRInt32 aEnumerationItemType)
00120 {
00121   mDocShellType = aEnumerationItemType;
00122   ClearState();
00123   return NS_OK;
00124 }
00125 
00126 nsresult nsDocShellEnumerator::First()
00127 {
00128   mCurIndex = 0;
00129   return EnsureDocShellArray();
00130 }
00131 
00132 nsresult nsDocShellEnumerator::EnsureDocShellArray()
00133 {
00134   if (!mItemArray)
00135   {
00136     mItemArray = new nsVoidArray;
00137     if (!mItemArray) return NS_ERROR_OUT_OF_MEMORY;
00138   
00139     return BuildDocShellArray(*mItemArray);
00140   }
00141   
00142   return NS_OK;
00143 }
00144 
00145 nsresult nsDocShellEnumerator::ClearState()
00146 {
00147   delete mItemArray;
00148   mItemArray = nsnull;
00149   
00150   mCurIndex = 0;
00151   return NS_OK;
00152 }
00153 
00154 nsresult nsDocShellEnumerator::BuildDocShellArray(nsVoidArray& inItemArray)
00155 {
00156   NS_ENSURE_TRUE(mRootItem, NS_ERROR_NOT_INITIALIZED);
00157   inItemArray.Clear();
00158   return BuildArrayRecursive(mRootItem, inItemArray);
00159 }
00160 
00161 nsresult nsDocShellForwardsEnumerator::BuildArrayRecursive(nsIDocShellTreeItem* inItem, nsVoidArray& inItemArray)
00162 {
00163   nsresult rv;
00164   nsCOMPtr<nsIDocShellTreeNode> itemAsNode = do_QueryInterface(inItem, &rv);
00165   if (NS_FAILED(rv)) return rv;
00166 
00167   PRInt32   itemType;
00168   // add this item to the array
00169   if ((mDocShellType == nsIDocShellTreeItem::typeAll) ||
00170       (NS_SUCCEEDED(inItem->GetItemType(&itemType)) && (itemType == mDocShellType)))
00171   {
00172     rv = inItemArray.AppendElement((void *)inItem);
00173     if (NS_FAILED(rv)) return rv;
00174   }
00175 
00176   PRInt32   numChildren;
00177   rv = itemAsNode->GetChildCount(&numChildren);
00178   if (NS_FAILED(rv)) return rv;
00179   
00180   for (PRInt32 i = 0; i < numChildren; ++i)
00181   {
00182     nsCOMPtr<nsIDocShellTreeItem> curChild;
00183     rv = itemAsNode->GetChildAt(i, getter_AddRefs(curChild));
00184     if (NS_FAILED(rv)) return rv;
00185       
00186     rv = BuildArrayRecursive(curChild, inItemArray);
00187     if (NS_FAILED(rv)) return rv;
00188   }
00189 
00190   return NS_OK;
00191 }
00192 
00193 
00194 nsresult nsDocShellBackwardsEnumerator::BuildArrayRecursive(nsIDocShellTreeItem* inItem, nsVoidArray& inItemArray)
00195 {
00196   nsresult rv;
00197   nsCOMPtr<nsIDocShellTreeNode> itemAsNode = do_QueryInterface(inItem, &rv);
00198   if (NS_FAILED(rv)) return rv;
00199 
00200   PRInt32   numChildren;
00201   rv = itemAsNode->GetChildCount(&numChildren);
00202   if (NS_FAILED(rv)) return rv;
00203   
00204   for (PRInt32 i = numChildren - 1; i >= 0; --i)
00205   {
00206     nsCOMPtr<nsIDocShellTreeItem> curChild;
00207     rv = itemAsNode->GetChildAt(i, getter_AddRefs(curChild));
00208     if (NS_FAILED(rv)) return rv;
00209       
00210     rv = BuildArrayRecursive(curChild, inItemArray);
00211     if (NS_FAILED(rv)) return rv;
00212   }
00213 
00214   PRInt32   itemType;
00215   // add this item to the array
00216   if ((mDocShellType == nsIDocShellTreeItem::typeAll) ||
00217       (NS_SUCCEEDED(inItem->GetItemType(&itemType)) && (itemType == mDocShellType)))
00218   {
00219     rv = inItemArray.AppendElement((void *)inItem);
00220     if (NS_FAILED(rv)) return rv;
00221   }
00222 
00223 
00224   return NS_OK;
00225 }
00226 
00227