LCOV - code coverage report
Current view: directory - layout/xul/base/src/tree/src - nsTreeColumns.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 327 2 0.6 %
Date: 2012-06-02 Functions: 53 2 3.8 %

       1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2                 : /* ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is mozilla.org code.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is
      18                 :  * Netscape Communications Corporation.
      19                 :  * Portions created by the Initial Developer are Copyright (C) 2003
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *   Dave Hyatt <hyatt@mozilla.org> (Original Author)
      24                 :  *   Jan Varga <varga@ku.sk>
      25                 :  *   Ehsan Akhgari <ehsan.akhgari@gmail.com>
      26                 :  *
      27                 :  * Alternatively, the contents of this file may be used under the terms of
      28                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      29                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      30                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      31                 :  * of those above. If you wish to allow use of your version of this file only
      32                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      33                 :  * use your version of this file under the terms of the MPL, indicate your
      34                 :  * decision by deleting the provisions above and replace them with the notice
      35                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      36                 :  * the provisions above, a recipient may use your version of this file under
      37                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      38                 :  *
      39                 :  * ***** END LICENSE BLOCK ***** */
      40                 : 
      41                 : #include "nsINameSpaceManager.h"
      42                 : #include "nsGkAtoms.h"
      43                 : #include "nsIDOMElement.h"
      44                 : #include "nsIBoxObject.h"
      45                 : #include "nsIDocument.h"
      46                 : #include "nsTreeColumns.h"
      47                 : #include "nsTreeUtils.h"
      48                 : #include "nsStyleContext.h"
      49                 : #include "nsDOMClassInfoID.h"
      50                 : #include "nsINodeInfo.h"
      51                 : #include "nsContentUtils.h"
      52                 : #include "nsTreeBodyFrame.h"
      53                 : 
      54                 : // Column class that caches all the info about our column.
      55               0 : nsTreeColumn::nsTreeColumn(nsTreeColumns* aColumns, nsIContent* aContent)
      56                 :   : mContent(aContent),
      57                 :     mColumns(aColumns),
      58               0 :     mPrevious(nsnull)
      59                 : {
      60               0 :   NS_ASSERTION(aContent &&
      61                 :                aContent->NodeInfo()->Equals(nsGkAtoms::treecol,
      62                 :                                             kNameSpaceID_XUL),
      63                 :                "nsTreeColumn's content must be a <xul:treecol>");
      64                 : 
      65               0 :   Invalidate();
      66               0 : }
      67                 : 
      68               0 : nsTreeColumn::~nsTreeColumn()
      69                 : {
      70               0 :   if (mNext) {
      71               0 :     mNext->SetPrevious(nsnull);
      72                 :   }
      73               0 : }
      74                 : 
      75            1464 : NS_IMPL_CYCLE_COLLECTION_CLASS(nsTreeColumn)
      76               0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsTreeColumn)
      77               0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mContent)
      78               0 :   if (tmp->mNext) {
      79               0 :     tmp->mNext->SetPrevious(nsnull);
      80               0 :     NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mNext)
      81                 :   }
      82               0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
      83               0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsTreeColumn)
      84               0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mContent)
      85               0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mNext)
      86               0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
      87                 : 
      88               0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(nsTreeColumn)
      89               0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(nsTreeColumn)
      90                 : 
      91                 : DOMCI_DATA(TreeColumn, nsTreeColumn)
      92                 : 
      93                 : // QueryInterface implementation for nsTreeColumn
      94               0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsTreeColumn)
      95               0 :   NS_INTERFACE_MAP_ENTRY(nsITreeColumn)
      96               0 :   NS_INTERFACE_MAP_ENTRY(nsISupports)
      97               0 :   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(TreeColumn)
      98               0 :   if (aIID.Equals(NS_GET_IID(nsTreeColumn))) {
      99               0 :     AddRef();
     100               0 :     *aInstancePtr = this;
     101               0 :     return NS_OK;
     102                 :   }
     103                 :   else
     104               0 : NS_INTERFACE_MAP_END
     105                 : 
     106                 : nsIFrame*
     107               0 : nsTreeColumn::GetFrame()
     108                 : {
     109               0 :   NS_ENSURE_TRUE(mContent, nsnull);
     110                 : 
     111               0 :   return mContent->GetPrimaryFrame();
     112                 : }
     113                 : 
     114                 : bool
     115               0 : nsTreeColumn::IsLastVisible(nsTreeBodyFrame* aBodyFrame)
     116                 : {
     117               0 :   NS_ASSERTION(GetFrame(), "should have checked for this already");
     118                 : 
     119                 :   // cyclers are fixed width, don't adjust them
     120               0 :   if (IsCycler())
     121               0 :     return false;
     122                 : 
     123                 :   // we're certainly not the last visible if we're not visible
     124               0 :   if (GetFrame()->GetRect().width == 0)
     125               0 :     return false;
     126                 : 
     127                 :   // try to find a visible successor
     128               0 :   for (nsTreeColumn *next = GetNext(); next; next = next->GetNext()) {
     129               0 :     nsIFrame* frame = next->GetFrame();
     130               0 :     if (frame && frame->GetRect().width > 0)
     131               0 :       return false;
     132                 :   }
     133               0 :   return true;
     134                 : }
     135                 : 
     136                 : nsresult
     137               0 : nsTreeColumn::GetRect(nsTreeBodyFrame* aBodyFrame, nscoord aY, nscoord aHeight, nsRect* aResult)
     138                 : {
     139               0 :   nsIFrame* frame = GetFrame();
     140               0 :   if (!frame) {
     141               0 :     *aResult = nsRect();
     142               0 :     return NS_ERROR_FAILURE;
     143                 :   }
     144                 : 
     145               0 :   bool isRTL = aBodyFrame->GetStyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL;
     146               0 :   *aResult = frame->GetRect();
     147               0 :   aResult->y = aY;
     148               0 :   aResult->height = aHeight;
     149               0 :   if (isRTL)
     150               0 :     aResult->x += aBodyFrame->mAdjustWidth;
     151               0 :   else if (IsLastVisible(aBodyFrame))
     152               0 :     aResult->width += aBodyFrame->mAdjustWidth;
     153               0 :   return NS_OK;
     154                 : }
     155                 : 
     156                 : nsresult
     157               0 : nsTreeColumn::GetXInTwips(nsTreeBodyFrame* aBodyFrame, nscoord* aResult)
     158                 : {
     159               0 :   nsIFrame* frame = GetFrame();
     160               0 :   if (!frame) {
     161               0 :     *aResult = 0;
     162               0 :     return NS_ERROR_FAILURE;
     163                 :   }
     164               0 :   *aResult = frame->GetRect().x;
     165               0 :   return NS_OK;
     166                 : }
     167                 : 
     168                 : nsresult
     169               0 : nsTreeColumn::GetWidthInTwips(nsTreeBodyFrame* aBodyFrame, nscoord* aResult)
     170                 : {
     171               0 :   nsIFrame* frame = GetFrame();
     172               0 :   if (!frame) {
     173               0 :     *aResult = 0;
     174               0 :     return NS_ERROR_FAILURE;
     175                 :   }
     176               0 :   *aResult = frame->GetRect().width;
     177               0 :   if (IsLastVisible(aBodyFrame))
     178               0 :     *aResult += aBodyFrame->mAdjustWidth;
     179               0 :   return NS_OK;
     180                 : }
     181                 : 
     182                 : 
     183                 : NS_IMETHODIMP
     184               0 : nsTreeColumn::GetElement(nsIDOMElement** aElement)
     185                 : {
     186               0 :   if (mContent) {
     187               0 :     return CallQueryInterface(mContent, aElement);
     188                 :   }
     189               0 :   *aElement = nsnull;
     190               0 :   return NS_ERROR_FAILURE;
     191                 : }
     192                 : 
     193                 : NS_IMETHODIMP
     194               0 : nsTreeColumn::GetColumns(nsITreeColumns** aColumns)
     195                 : {
     196               0 :   NS_IF_ADDREF(*aColumns = mColumns);
     197               0 :   return NS_OK;
     198                 : }
     199                 : 
     200                 : NS_IMETHODIMP
     201               0 : nsTreeColumn::GetX(PRInt32* aX)
     202                 : {
     203               0 :   nsIFrame* frame = GetFrame();
     204               0 :   NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
     205                 : 
     206               0 :   *aX = nsPresContext::AppUnitsToIntCSSPixels(frame->GetRect().x);
     207               0 :   return NS_OK;
     208                 : }
     209                 : 
     210                 : NS_IMETHODIMP
     211               0 : nsTreeColumn::GetWidth(PRInt32* aWidth)
     212                 : {
     213               0 :   nsIFrame* frame = GetFrame();
     214               0 :   NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
     215                 : 
     216               0 :   *aWidth = nsPresContext::AppUnitsToIntCSSPixels(frame->GetRect().width);
     217               0 :   return NS_OK;
     218                 : }
     219                 : 
     220                 : NS_IMETHODIMP
     221               0 : nsTreeColumn::GetId(nsAString& aId)
     222                 : {
     223               0 :   aId = GetId();
     224               0 :   return NS_OK;
     225                 : }
     226                 : 
     227                 : NS_IMETHODIMP
     228               0 : nsTreeColumn::GetIdConst(const PRUnichar** aIdConst)
     229                 : {
     230               0 :   *aIdConst = mId.get();
     231               0 :   return NS_OK;
     232                 : }
     233                 : 
     234                 : NS_IMETHODIMP
     235               0 : nsTreeColumn::GetAtom(nsIAtom** aAtom)
     236                 : {
     237               0 :   NS_IF_ADDREF(*aAtom = GetAtom());
     238               0 :   return NS_OK;
     239                 : }
     240                 : 
     241                 : NS_IMETHODIMP
     242               0 : nsTreeColumn::GetIndex(PRInt32* aIndex)
     243                 : {
     244               0 :   *aIndex = GetIndex();
     245               0 :   return NS_OK;
     246                 : }
     247                 : 
     248                 : NS_IMETHODIMP
     249               0 : nsTreeColumn::GetPrimary(bool* aPrimary)
     250                 : {
     251               0 :   *aPrimary = IsPrimary();
     252               0 :   return NS_OK;
     253                 : }
     254                 : 
     255                 : NS_IMETHODIMP
     256               0 : nsTreeColumn::GetCycler(bool* aCycler)
     257                 : {
     258               0 :   *aCycler = IsCycler();
     259               0 :   return NS_OK;
     260                 : }
     261                 : 
     262                 : NS_IMETHODIMP
     263               0 : nsTreeColumn::GetEditable(bool* aEditable)
     264                 : {
     265               0 :   *aEditable = IsEditable();
     266               0 :   return NS_OK;
     267                 : }
     268                 : 
     269                 : NS_IMETHODIMP
     270               0 : nsTreeColumn::GetSelectable(bool* aSelectable)
     271                 : {
     272               0 :   *aSelectable = IsSelectable();
     273               0 :   return NS_OK;
     274                 : }
     275                 : 
     276                 : NS_IMETHODIMP
     277               0 : nsTreeColumn::GetType(PRInt16* aType)
     278                 : {
     279               0 :   *aType = GetType();
     280               0 :   return NS_OK;
     281                 : }
     282                 : 
     283                 : NS_IMETHODIMP
     284               0 : nsTreeColumn::GetNext(nsITreeColumn** _retval)
     285                 : {
     286               0 :   NS_IF_ADDREF(*_retval = GetNext());
     287               0 :   return NS_OK;
     288                 : }
     289                 : 
     290                 : NS_IMETHODIMP
     291               0 : nsTreeColumn::GetPrevious(nsITreeColumn** _retval)
     292                 : {
     293               0 :   NS_IF_ADDREF(*_retval = GetPrevious());
     294               0 :   return NS_OK;
     295                 : }
     296                 : 
     297                 : NS_IMETHODIMP
     298               0 : nsTreeColumn::Invalidate()
     299                 : {
     300               0 :   nsIFrame* frame = GetFrame();
     301               0 :   NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
     302                 : 
     303                 :   // Fetch the Id.
     304               0 :   mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::id, mId);
     305                 : 
     306                 :   // If we have an Id, cache the Id as an atom.
     307               0 :   if (!mId.IsEmpty()) {
     308               0 :     mAtom = do_GetAtom(mId);
     309                 :   }
     310                 : 
     311                 :   // Cache our index.
     312               0 :   nsTreeUtils::GetColumnIndex(mContent, &mIndex);
     313                 : 
     314               0 :   const nsStyleVisibility* vis = frame->GetStyleVisibility();
     315                 : 
     316                 :   // Cache our text alignment policy.
     317               0 :   const nsStyleText* textStyle = frame->GetStyleText();
     318                 : 
     319               0 :   mTextAlignment = textStyle->mTextAlign;
     320                 :   // DEFAULT or END alignment sometimes means RIGHT
     321               0 :   if ((mTextAlignment == NS_STYLE_TEXT_ALIGN_DEFAULT &&
     322                 :        vis->mDirection == NS_STYLE_DIRECTION_RTL) ||
     323                 :       (mTextAlignment == NS_STYLE_TEXT_ALIGN_END &&
     324                 :        vis->mDirection == NS_STYLE_DIRECTION_LTR)) {
     325               0 :     mTextAlignment = NS_STYLE_TEXT_ALIGN_RIGHT;
     326               0 :   } else if (mTextAlignment == NS_STYLE_TEXT_ALIGN_DEFAULT ||
     327                 :              mTextAlignment == NS_STYLE_TEXT_ALIGN_END) {
     328               0 :     mTextAlignment = NS_STYLE_TEXT_ALIGN_LEFT;
     329                 :   }
     330                 : 
     331                 :   // Figure out if we're the primary column (that has to have indentation
     332                 :   // and twisties drawn.
     333               0 :   mIsPrimary = mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::primary,
     334               0 :                                      nsGkAtoms::_true, eCaseMatters);
     335                 : 
     336                 :   // Figure out if we're a cycling column (one that doesn't cause a selection
     337                 :   // to happen).
     338               0 :   mIsCycler = mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::cycler,
     339               0 :                                     nsGkAtoms::_true, eCaseMatters);
     340                 : 
     341               0 :   mIsEditable = mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::editable,
     342               0 :                                      nsGkAtoms::_true, eCaseMatters);
     343                 : 
     344               0 :   mIsSelectable = !mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::selectable,
     345               0 :                                          nsGkAtoms::_false, eCaseMatters);
     346                 : 
     347               0 :   mOverflow = mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::overflow,
     348               0 :                                     nsGkAtoms::_true, eCaseMatters);
     349                 : 
     350                 :   // Figure out our column type. Default type is text.
     351               0 :   mType = nsITreeColumn::TYPE_TEXT;
     352                 :   static nsIContent::AttrValuesArray typestrings[] =
     353                 :     {&nsGkAtoms::checkbox, &nsGkAtoms::progressmeter, nsnull};
     354               0 :   switch (mContent->FindAttrValueIn(kNameSpaceID_None, nsGkAtoms::type,
     355               0 :                                     typestrings, eCaseMatters)) {
     356               0 :     case 0: mType = nsITreeColumn::TYPE_CHECKBOX; break;
     357               0 :     case 1: mType = nsITreeColumn::TYPE_PROGRESSMETER; break;
     358                 :   }
     359                 : 
     360                 :   // Fetch the crop style.
     361               0 :   mCropStyle = 0;
     362                 :   static nsIContent::AttrValuesArray cropstrings[] =
     363                 :     {&nsGkAtoms::center, &nsGkAtoms::left, &nsGkAtoms::start, nsnull};
     364               0 :   switch (mContent->FindAttrValueIn(kNameSpaceID_None, nsGkAtoms::crop,
     365               0 :                                     cropstrings, eCaseMatters)) {
     366                 :     case 0:
     367               0 :       mCropStyle = 1;
     368               0 :       break;
     369                 :     case 1:
     370                 :     case 2:
     371               0 :       mCropStyle = 2;
     372               0 :       break;
     373                 :   }
     374                 : 
     375               0 :   return NS_OK;
     376                 : }
     377                 : 
     378                 : 
     379               0 : nsTreeColumns::nsTreeColumns(nsITreeBoxObject* aTree)
     380                 :   : mTree(aTree),
     381               0 :     mFirstColumn(nsnull)
     382                 : {
     383               0 : }
     384                 : 
     385               0 : nsTreeColumns::~nsTreeColumns()
     386                 : {
     387               0 :   nsTreeColumns::InvalidateColumns();
     388               0 : }
     389                 : 
     390                 : DOMCI_DATA(TreeColumns, nsTreeColumns)
     391                 : 
     392                 : // QueryInterface implementation for nsTreeColumns
     393               0 : NS_INTERFACE_MAP_BEGIN(nsTreeColumns)
     394               0 :   NS_INTERFACE_MAP_ENTRY(nsITreeColumns)
     395               0 :   NS_INTERFACE_MAP_ENTRY(nsISupports)
     396               0 :   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(TreeColumns)
     397               0 : NS_INTERFACE_MAP_END
     398                 :                                                                                 
     399               0 : NS_IMPL_ADDREF(nsTreeColumns)
     400               0 : NS_IMPL_RELEASE(nsTreeColumns)
     401                 : 
     402                 : NS_IMETHODIMP
     403               0 : nsTreeColumns::GetTree(nsITreeBoxObject** _retval)
     404                 : {
     405               0 :   NS_IF_ADDREF(*_retval = mTree);
     406               0 :   return NS_OK;
     407                 : }
     408                 : 
     409                 : NS_IMETHODIMP
     410               0 : nsTreeColumns::GetCount(PRInt32* _retval)
     411                 : {
     412               0 :   EnsureColumns();
     413               0 :   *_retval = 0;
     414               0 :   for (nsTreeColumn* currCol = mFirstColumn; currCol; currCol = currCol->GetNext()) {
     415               0 :     ++(*_retval);
     416                 :   }
     417               0 :   return NS_OK;
     418                 : }
     419                 : 
     420                 : NS_IMETHODIMP
     421               0 : nsTreeColumns::GetLength(PRInt32* _retval)
     422                 : {
     423               0 :   return GetCount(_retval);
     424                 : }
     425                 : 
     426                 : NS_IMETHODIMP
     427               0 : nsTreeColumns::GetFirstColumn(nsITreeColumn** _retval)
     428                 : {
     429               0 :   NS_IF_ADDREF(*_retval = GetFirstColumn());
     430               0 :   return NS_OK;
     431                 : }
     432                 : 
     433                 : NS_IMETHODIMP
     434               0 : nsTreeColumns::GetLastColumn(nsITreeColumn** _retval)
     435                 : {
     436               0 :   EnsureColumns();
     437               0 :   *_retval = nsnull;
     438               0 :   nsTreeColumn* currCol = mFirstColumn;
     439               0 :   while (currCol) {
     440               0 :     nsTreeColumn* next = currCol->GetNext();
     441               0 :     if (!next) {
     442               0 :       NS_ADDREF(*_retval = currCol);
     443               0 :       break;
     444                 :     }
     445               0 :     currCol = next;
     446                 :   }
     447               0 :   return NS_OK;
     448                 : }
     449                 : 
     450                 : NS_IMETHODIMP
     451               0 : nsTreeColumns::GetPrimaryColumn(nsITreeColumn** _retval)
     452                 : {
     453               0 :   NS_IF_ADDREF(*_retval = GetPrimaryColumn());
     454               0 :   return NS_OK;
     455                 : }
     456                 : 
     457                 : NS_IMETHODIMP
     458               0 : nsTreeColumns::GetSortedColumn(nsITreeColumn** _retval)
     459                 : {
     460               0 :   EnsureColumns();
     461               0 :   *_retval = nsnull;
     462               0 :   for (nsTreeColumn* currCol = mFirstColumn; currCol; currCol = currCol->GetNext()) {
     463               0 :     if (currCol->mContent &&
     464                 :         nsContentUtils::HasNonEmptyAttr(currCol->mContent, kNameSpaceID_None,
     465               0 :                                         nsGkAtoms::sortDirection)) {
     466               0 :       NS_ADDREF(*_retval = currCol);
     467               0 :       return NS_OK;
     468                 :     }
     469                 :   }
     470               0 :   return NS_OK;
     471                 : }
     472                 : 
     473                 : NS_IMETHODIMP
     474               0 : nsTreeColumns::GetKeyColumn(nsITreeColumn** _retval)
     475                 : {
     476               0 :   EnsureColumns();
     477               0 :   *_retval = nsnull;
     478                 : 
     479                 :   nsTreeColumn* first;
     480                 :   nsTreeColumn* primary;
     481                 :   nsTreeColumn* sorted;
     482               0 :   first = primary = sorted = nsnull;
     483                 : 
     484               0 :   for (nsTreeColumn* currCol = mFirstColumn; currCol; currCol = currCol->GetNext()) {
     485                 :     // Skip hidden columns.
     486               0 :     if (!currCol->mContent ||
     487               0 :         currCol->mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::hidden,
     488               0 :                                        nsGkAtoms::_true, eCaseMatters))
     489               0 :       continue;
     490                 : 
     491                 :     // Skip non-text column
     492               0 :     if (currCol->GetType() != nsITreeColumn::TYPE_TEXT)
     493               0 :       continue;
     494                 : 
     495               0 :     if (!first)
     496               0 :       first = currCol;
     497                 :     
     498               0 :     if (nsContentUtils::HasNonEmptyAttr(currCol->mContent, kNameSpaceID_None,
     499               0 :                                         nsGkAtoms::sortDirection)) {
     500                 :       // Use sorted column as the key.
     501               0 :       sorted = currCol;
     502               0 :       break;
     503                 :     }
     504                 : 
     505               0 :     if (currCol->IsPrimary())
     506               0 :       if (!primary)
     507               0 :         primary = currCol;
     508                 :   }
     509                 : 
     510               0 :   if (sorted)
     511               0 :     *_retval = sorted;
     512               0 :   else if (primary)
     513               0 :     *_retval = primary;
     514                 :   else
     515               0 :     *_retval = first;
     516                 : 
     517               0 :   NS_IF_ADDREF(*_retval);
     518               0 :   return NS_OK;
     519                 : }
     520                 : 
     521                 : NS_IMETHODIMP
     522               0 : nsTreeColumns::GetColumnFor(nsIDOMElement* aElement, nsITreeColumn** _retval)
     523                 : {
     524               0 :   EnsureColumns();
     525               0 :   *_retval = nsnull;
     526               0 :   nsCOMPtr<nsIContent> element = do_QueryInterface(aElement);
     527               0 :   for (nsTreeColumn* currCol = mFirstColumn; currCol; currCol = currCol->GetNext()) {
     528               0 :     if (currCol->mContent == element) {
     529               0 :       NS_ADDREF(*_retval = currCol);
     530               0 :       break;
     531                 :     }
     532                 :   }
     533                 : 
     534               0 :   return NS_OK;
     535                 : }
     536                 : 
     537                 : nsITreeColumn*
     538               0 : nsTreeColumns::GetNamedColumn(const nsAString& aId)
     539                 : {
     540               0 :   EnsureColumns();
     541               0 :   for (nsTreeColumn* currCol = mFirstColumn; currCol; currCol = currCol->GetNext()) {
     542               0 :     if (currCol->GetId().Equals(aId)) {
     543               0 :       return currCol;
     544                 :     }
     545                 :   }
     546               0 :   return nsnull;
     547                 : }
     548                 : 
     549                 : NS_IMETHODIMP
     550               0 : nsTreeColumns::GetNamedColumn(const nsAString& aId, nsITreeColumn** _retval)
     551                 : {
     552               0 :   NS_IF_ADDREF(*_retval = GetNamedColumn(aId));
     553               0 :   return NS_OK;
     554                 : }
     555                 : 
     556                 : nsITreeColumn*
     557               0 : nsTreeColumns::GetColumnAt(PRInt32 aIndex)
     558                 : {
     559               0 :   EnsureColumns();
     560               0 :   for (nsTreeColumn* currCol = mFirstColumn; currCol; currCol = currCol->GetNext()) {
     561               0 :     if (currCol->GetIndex() == aIndex) {
     562               0 :       return currCol;
     563                 :     }
     564                 :   }
     565               0 :   return nsnull;
     566                 : }
     567                 : 
     568                 : NS_IMETHODIMP
     569               0 : nsTreeColumns::GetColumnAt(PRInt32 aIndex, nsITreeColumn** _retval)
     570                 : {
     571               0 :   NS_IF_ADDREF(*_retval = GetColumnAt(aIndex));
     572               0 :   return NS_OK;
     573                 : }
     574                 : 
     575                 : NS_IMETHODIMP
     576               0 : nsTreeColumns::InvalidateColumns()
     577                 : {
     578               0 :   for (nsTreeColumn* currCol = mFirstColumn; currCol;
     579                 :        currCol = currCol->GetNext()) {
     580               0 :     currCol->SetColumns(nsnull);
     581                 :   }
     582               0 :   NS_IF_RELEASE(mFirstColumn);
     583               0 :   return NS_OK;
     584                 : }
     585                 : 
     586                 : NS_IMETHODIMP
     587               0 : nsTreeColumns::RestoreNaturalOrder()
     588                 : {
     589               0 :   if (!mTree)
     590               0 :     return NS_OK;
     591                 : 
     592               0 :   nsCOMPtr<nsIBoxObject> boxObject = do_QueryInterface(mTree);
     593               0 :   nsCOMPtr<nsIDOMElement> element;
     594               0 :   boxObject->GetElement(getter_AddRefs(element));
     595               0 :   nsCOMPtr<nsIContent> content = do_QueryInterface(element);
     596                 : 
     597                 :   // Strong ref, since we'll be setting attributes
     598                 :   nsCOMPtr<nsIContent> colsContent =
     599               0 :     nsTreeUtils::GetImmediateChild(content, nsGkAtoms::treecols);
     600               0 :   if (!colsContent)
     601               0 :     return NS_OK;
     602                 : 
     603               0 :   PRUint32 numChildren = colsContent->GetChildCount();
     604               0 :   for (PRUint32 i = 0; i < numChildren; ++i) {
     605               0 :     nsIContent *child = colsContent->GetChildAt(i);
     606               0 :     nsAutoString ordinal;
     607               0 :     ordinal.AppendInt(i);
     608               0 :     child->SetAttr(kNameSpaceID_None, nsGkAtoms::ordinal, ordinal, true);
     609                 :   }
     610                 : 
     611               0 :   nsTreeColumns::InvalidateColumns();
     612                 : 
     613               0 :   mTree->Invalidate();
     614                 : 
     615               0 :   return NS_OK;
     616                 : }
     617                 : 
     618                 : nsTreeColumn*
     619               0 : nsTreeColumns::GetPrimaryColumn()
     620                 : {
     621               0 :   EnsureColumns();
     622               0 :   for (nsTreeColumn* currCol = mFirstColumn; currCol; currCol = currCol->GetNext()) {
     623               0 :     if (currCol->IsPrimary()) {
     624               0 :       return currCol;
     625                 :     }
     626                 :   }
     627               0 :   return nsnull;
     628                 : }
     629                 : 
     630                 : void
     631               0 : nsTreeColumns::EnsureColumns()
     632                 : {
     633               0 :   if (mTree && !mFirstColumn) {
     634               0 :     nsCOMPtr<nsIBoxObject> boxObject = do_QueryInterface(mTree);
     635               0 :     nsCOMPtr<nsIDOMElement> treeElement;
     636               0 :     boxObject->GetElement(getter_AddRefs(treeElement));
     637               0 :     nsCOMPtr<nsIContent> treeContent = do_QueryInterface(treeElement);
     638                 : 
     639                 :     nsIContent* colsContent =
     640               0 :       nsTreeUtils::GetDescendantChild(treeContent, nsGkAtoms::treecols);
     641               0 :     if (!colsContent)
     642                 :       return;
     643                 : 
     644                 :     nsIContent* colContent =
     645               0 :       nsTreeUtils::GetDescendantChild(colsContent, nsGkAtoms::treecol);
     646               0 :     if (!colContent)
     647                 :       return;
     648                 : 
     649               0 :     nsIFrame* colFrame = colContent->GetPrimaryFrame();
     650               0 :     if (!colFrame)
     651                 :       return;
     652                 : 
     653               0 :     colFrame = colFrame->GetParent();
     654               0 :     if (!colFrame)
     655                 :       return;
     656                 : 
     657               0 :     colFrame = colFrame->GetFirstPrincipalChild();
     658               0 :     if (!colFrame)
     659                 :       return;
     660                 : 
     661                 :     // Now that we have the first visible column,
     662                 :     // we can enumerate the columns in visible order
     663               0 :     nsTreeColumn* currCol = nsnull;
     664               0 :     while (colFrame) {
     665               0 :       nsIContent* colContent = colFrame->GetContent();
     666                 : 
     667               0 :       if (colContent->NodeInfo()->Equals(nsGkAtoms::treecol,
     668               0 :                                          kNameSpaceID_XUL)) {
     669                 :         // Create a new column structure.
     670               0 :         nsTreeColumn* col = new nsTreeColumn(this, colContent);
     671               0 :         if (!col)
     672                 :           return;
     673                 : 
     674               0 :         if (currCol) {
     675               0 :           currCol->SetNext(col);
     676               0 :           col->SetPrevious(currCol);
     677                 :         }
     678                 :         else {
     679               0 :           NS_ADDREF(mFirstColumn = col);
     680                 :         }
     681               0 :         currCol = col;
     682                 :       }
     683                 : 
     684               0 :       colFrame = colFrame->GetNextSibling();
     685                 :     }
     686                 :   }
     687            4392 : }

Generated by: LCOV version 1.7