Back to index

lightning-sunbird  0.9+nobinonly
nsTreeUtils.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
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 Communicator client 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) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Chris Waterson <waterson@netscape.com>
00024  *   Jan Varga <varga@ku.sk>
00025  *   Nate Nielsen <nielsen@memberwebs.com>
00026  *
00027  * Alternatively, the contents of this file may be used under the terms of
00028  * either of the GNU General Public License Version 2 or later (the "GPL"),
00029  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00030  * in which case the provisions of the GPL or the LGPL are applicable instead
00031  * of those above. If you wish to allow use of your version of this file only
00032  * under the terms of either the GPL or the LGPL, and not to allow others to
00033  * use your version of this file under the terms of the MPL, indicate your
00034  * decision by deleting the provisions above and replace them with the notice
00035  * and other provisions required by the GPL or the LGPL. If you do not delete
00036  * the provisions above, a recipient may use your version of this file under
00037  * the terms of any one of the MPL, the GPL or the LGPL.
00038  *
00039  * ***** END LICENSE BLOCK ***** */
00040 
00041 #include "nsReadableUtils.h"
00042 #include "nsTreeUtils.h"
00043 #include "nsChildIterator.h"
00044 #include "nsCRT.h"
00045 #include "nsIAtom.h"
00046 #include "nsINameSpaceManager.h"
00047 #include "nsXULAtoms.h"
00048 #include "nsINodeInfo.h"
00049 
00050 nsresult
00051 nsTreeUtils::TokenizeProperties(const nsAString& aProperties, nsISupportsArray* aPropertiesArray)
00052 {
00053   NS_PRECONDITION(aPropertiesArray != nsnull, "null ptr");
00054   if (! aPropertiesArray)
00055      return NS_ERROR_NULL_POINTER;
00056 
00057   nsAString::const_iterator end;
00058   aProperties.EndReading(end);
00059 
00060   nsAString::const_iterator iter;
00061   aProperties.BeginReading(iter);
00062 
00063   do {
00064     // Skip whitespace
00065     while (iter != end && nsCRT::IsAsciiSpace(*iter))
00066       ++iter;
00067 
00068     // If only whitespace, we're done
00069     if (iter == end)
00070       break;
00071 
00072     // Note the first non-whitespace character
00073     nsAString::const_iterator first = iter;
00074 
00075     // Advance to the next whitespace character
00076     while (iter != end && ! nsCRT::IsAsciiSpace(*iter))
00077       ++iter;
00078 
00079     // XXX this would be nonsensical
00080     NS_ASSERTION(iter != first, "eh? something's wrong here");
00081     if (iter == first)
00082       break;
00083 
00084     nsCOMPtr<nsIAtom> atom = do_GetAtom(Substring(first, iter));
00085     aPropertiesArray->AppendElement(atom);
00086   } while (iter != end);
00087 
00088   return NS_OK;
00089 }
00090 
00091 nsresult
00092 nsTreeUtils::GetImmediateChild(nsIContent* aContainer, nsIAtom* aTag,
00093                                nsIContent** aResult)
00094 {
00095   ChildIterator iter, last;
00096   for (ChildIterator::Init(aContainer, &iter, &last); iter != last; ++iter) {
00097     nsCOMPtr<nsIContent> child = *iter;
00098 
00099     if (child->Tag() == aTag) {
00100       NS_ADDREF(*aResult = child);
00101       return NS_OK;
00102     }
00103   }
00104 
00105   *aResult = nsnull;
00106   return NS_OK;
00107 }
00108 
00109 nsresult
00110 nsTreeUtils::GetDescendantChild(nsIContent* aContainer, nsIAtom* aTag, nsIContent** aResult)
00111 {
00112   ChildIterator iter, last;
00113   for (ChildIterator::Init(aContainer, &iter, &last); iter != last; ++iter) {
00114     nsCOMPtr<nsIContent> child = *iter;
00115     if (child->Tag() == aTag) {
00116       NS_ADDREF(*aResult = child);
00117       return NS_OK;
00118     }
00119     else {
00120       nsresult rv = GetDescendantChild(child, aTag, aResult);
00121       if(NS_FAILED(rv))
00122         return rv;
00123 
00124       if(*aResult)
00125         return NS_OK;
00126     }
00127   }
00128 
00129   *aResult = nsnull;
00130   return NS_OK;
00131 }
00132 
00133 nsresult
00134 nsTreeUtils::UpdateSortIndicators(nsIContent* aColumn, const nsAString& aDirection)
00135 {
00136   aColumn->SetAttr(kNameSpaceID_None, nsXULAtoms::sortDirection, aDirection, PR_TRUE);
00137   aColumn->SetAttr(kNameSpaceID_None, nsXULAtoms::sortActive, NS_LITERAL_STRING("true"), PR_TRUE);
00138 
00139   // Unset sort attribute(s) on the other columns
00140   nsCOMPtr<nsIContent> parentContent = aColumn->GetParent();
00141   if (parentContent) {
00142     nsINodeInfo *ni = parentContent->GetNodeInfo();
00143 
00144     if (ni && ni->Equals(nsXULAtoms::treecols, kNameSpaceID_XUL)) {
00145       PRUint32 numChildren = parentContent->GetChildCount();
00146       for (PRUint32 i = 0; i < numChildren; ++i) {
00147         nsCOMPtr<nsIContent> childContent = parentContent->GetChildAt(i);
00148 
00149         if (childContent) {
00150           ni = childContent->GetNodeInfo();
00151 
00152           if (ni && ni->Equals(nsXULAtoms::treecol, kNameSpaceID_XUL) &&
00153               childContent != aColumn) {
00154             childContent->UnsetAttr(kNameSpaceID_None,
00155                                     nsXULAtoms::sortDirection, PR_TRUE);
00156             childContent->UnsetAttr(kNameSpaceID_None,
00157                                     nsXULAtoms::sortActive, PR_TRUE);
00158           }
00159         }
00160       }
00161     }
00162   }
00163 
00164   return NS_OK;
00165 }
00166 
00167 nsresult
00168 nsTreeUtils::GetColumnIndex(nsIContent* aColumn, PRInt32* aResult)
00169 {
00170   nsIContent* parentContent = aColumn->GetParent();
00171   if (parentContent) {
00172     nsINodeInfo *ni = parentContent->GetNodeInfo();
00173 
00174     if (ni && ni->Equals(nsXULAtoms::treecols, kNameSpaceID_XUL)) {
00175       PRUint32 numChildren = parentContent->GetChildCount();
00176       PRInt32 colIndex = 0;
00177       for (PRUint32 i = 0; i < numChildren; ++i) {
00178         nsIContent *childContent = parentContent->GetChildAt(i);
00179 
00180         if (childContent) {
00181           ni = childContent->GetNodeInfo();
00182 
00183           if (ni && ni->Equals(nsXULAtoms::treecol, kNameSpaceID_XUL)) {
00184 
00185             if (childContent == aColumn) {
00186               *aResult = colIndex;
00187              return NS_OK;
00188             }
00189             colIndex++;
00190           }
00191         }
00192       }
00193     }
00194   }
00195 
00196   *aResult = -1;
00197   return NS_OK;
00198 }