Update contrib.
2 * Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
4 * This component and the accompanying materials are made available
5 * under the terms of "Eclipse Public License v1.0"
6 * which accompanies this distribution, and is available
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
29 const TInt KExpandedBitmapIndex = 0;
30 const TInt KClosedBitmapIndex = 1;
31 const TInt KIndentPerLevel=12;
32 const TInt KMaxParagraphLength = 128; // If a paragraph is longer than this length, truncate it
33 const TInt KWaitingTime = 500000;
38 // TOutlineEntry - constructors
41 TOutlineEntry::TOutlineEntry(TInt aParagraphNo, TInt aOutlineLevel, TInt aParaLen, TInt aParaPos, TBool aChild, TBool aLast)
42 : iParagraphNo(aParagraphNo),
43 iOutlineLevel(aOutlineLevel),
44 iParagraphLength(aParaLen),
45 iParagraphPos(aParaPos),
52 TOutlineEntry::TOutlineEntry()
62 // TOutlineMap - constructor
65 TOutlineMap::TOutlineMap(TInt aIndex, CHierListItem* aPtr)
75 COutlineMap* COutlineMap::NewL()
77 COutlineMap* self = new(ELeave) COutlineMap();
78 CleanupStack::PushL(self);
85 void COutlineMap::ConstructL()
87 // Create table with granularity of 5
88 iOutlineMapTable=new(ELeave) COutlineMapTable(5);
91 COutlineMap::~COutlineMap()
94 delete iOutlineMapTable;
98 void COutlineMap::BindL(TInt aRef, CHierListItem* aPtr)
100 TOutlineMap entry(aRef, aPtr);
102 // Check to see if either of these already exists
103 // When re-expanding elements, the same references can be bound to
104 // different pointers, and the same pointers can be bound to different
107 TInt items = iOutlineMapTable->Count();
110 for (count = 0; count<items; count++)
112 TOutlineMap* entry = &(*iOutlineMapTable)[count];
113 if (entry->iPtr == aPtr || entry->iIndex == aRef)
115 iOutlineMapTable->Delete(count);
121 iOutlineMapTable->AppendL(entry);
125 TInt COutlineMap::Index(CHierListItem* aPtr)
127 // Given an item pointer from the list box, return an index into the
128 // Outline Table, or -1 if it does not exist
130 const TInt items = iOutlineMapTable->Count();
133 for (count=0; count<items; count++)
135 TOutlineMap* entry = &(*iOutlineMapTable)[count];
136 if (entry->iPtr == aPtr) return entry->iIndex;
142 CHierListItem* COutlineMap::Ptr(TInt aIndex)
144 // Given an index into the Outline table, return a pointer to its
145 // entry in the list box, or NULL if it does not exist
147 const TInt items = iOutlineMapTable->Count();
150 for (count=0; count<items; count++)
152 TOutlineMap* entry = &(*iOutlineMapTable)[count];
153 if (entry->iIndex == aIndex) return entry->iPtr;
158 TBool COutlineMap::IndexPresent(TInt aIndex)
160 // Returns ETrue if the given index is present in the table
162 TInt items = iOutlineMapTable->Count();
165 for (count=0; count<items; count++)
167 TOutlineMap* entry = &(*iOutlineMapTable)[count];
168 if (entry->iIndex == aIndex) return ETrue;
180 COutlineHListBox::COutlineHListBox(CRichText* aText, TInt aCursorPos)
182 iCursorPos(aCursorPos)
187 TSize COutlineHListBox::MinimumSize()
189 // Specify the minimum size of this control
190 // Essential to make the control visible
191 TSize size(iSize.iWidth, iSize.iHeight);
192 if (!(iListBoxFlags&EScrollBarSizeExcluded) && iSBFrame && iSBFrame->HScrollBarVisibility()!=CEikScrollBarFrame::EOff)
193 size.iHeight += CEikScrollBar::DefaultScrollBarBreadth();
194 size+=iBorder.SizeDelta();
199 void COutlineHListBox::ConstructFromResourceL(TResourceReader& aReader)
201 // Called when creating the control from a dialog
202 // Reads the size of the control, then constructs the object
203 iSize.iWidth = aReader.ReadInt16();
204 iSize.iHeight = aReader.ReadInt16();
211 void COutlineHListBox::ConstructL()
213 // The NewL constructor will leave if there is nothing to show in outline view,
214 // so trap it, display a message, and leave without any error
216 TRAPD(ret, iModel = COutlineHListBoxModel::NewL(this, iText);)
217 if (ret == KErrNoOutline)
219 CEikonEnv::Static()->InfoMsg(R_WORD_NO_OUTLINE);
220 User::Leave(KErrNone);
223 // Get the open/close icons from the system
224 TFileName resource = _L("*");
225 CGulIcon* icon = iEikonEnv->CreateIconL(resource, EMbmWordOpenfdr);
226 CleanupStack::PushL(icon);
228 CArrayPtrFlat<CGulIcon>* icons = new(ELeave) CArrayPtrFlat<CGulIcon>(2);
229 CleanupStack::PushL(icons);
231 icons->AppendL(icon);
232 icon = iEikonEnv->CreateIconL(resource, EMbmWordClsdfdr);
234 CleanupStack::PushL(icon);
235 icons->AppendL(icon);
237 iItemDrawer = new(ELeave) COutlineHListItemDrawer((COutlineHListBoxModel*)iModel, iEikonEnv->NormalFont(), icons);
239 CleanupStack::Pop(3); // Cleanup the two icons and the array
241 // Create the initial entries of the list box
242 OutlineModel()->CreateRootListL();
246 // Expand the tree to show the current cursor position
247 TInt item = OutlineModel()->ExpandCurrentPositionL(iCursorPos);
251 // This updates the view to show the requested item no.
252 iView->SetCurrentItemIndex(item);
253 iView->SelectItemL(item);
254 iListBoxFlags |= EStateChanged;
257 CreateScrollBarFrameL();
258 ScrollBarFrame()->SetScrollBarVisibilityL(CEikScrollBarFrame::EOff, CEikScrollBarFrame::EAuto);
262 CListBoxView* COutlineHListBox::MakeViewClassInstanceL()
264 return (new(ELeave) COutlineHListBoxView);
268 TKeyResponse COutlineHListBox::OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType)
270 TInt currentItemIndex = iView->CurrentItemIndex();
271 COutlineHListBoxModel* listModel = (COutlineHListBoxModel*)iModel;
272 CHierListItem* itemToBeExpanded=listModel->Item(currentItemIndex);
274 TInt keyCode = aKeyEvent.iCode;
276 TBool expandKey = (keyCode == EKeyRightArrow || keyCode == '+');
277 TBool collapseKey = (keyCode == EKeyLeftArrow || keyCode == '-');
279 const TInt index=CurrentItemIndex();
280 CArrayFix<CHierListItem*>* listArray=HlModel()->HierListArray();
281 TBool itemHasChildren=EFalse;
286 if (!itemToBeExpanded->IsExpanded())
288 listModel->ExpandItemL(index);
289 CArrayFix<CHierListItem*>* newListArray=HlModel()->HierListArray();
290 if (index<newListArray->Count()-1)
291 itemHasChildren=((*newListArray)[index]->Level()==(*newListArray)[index+1]->Level()-1);
298 if (itemToBeExpanded->IsExpanded())
300 if (index<HlModel()->NumberOfItems()-1)
301 itemHasChildren=((*listArray)[index]->Level()==(*listArray)[index+1]->Level()-1);
302 listModel->CollapseItem(index);
307 if (expandKey || collapseKey)
309 iView->CalcDataWidth();
310 iView->CalcBottomItemIndex();
313 ((CHierarchicalListBoxView*)iView)->DrawFromItem(index);
315 ((CHierarchicalListBoxView*)iView)->DrawItem(index);
316 ReportListBoxEventL(MEikListBoxObserver::EEventItemActioned);
318 return EKeyWasConsumed;
321 return CEikHierarchicalListBox::OfferKeyEventL(aKeyEvent,aType);
327 void COutlineHListBox::ExpandAllItemsL()
329 CEikonEnv* eikonEnv=CEikonEnv::Static();
330 eikonEnv->BusyMsgL(R_WORD_EXPAND_OUTLINE, KWaitingTime);
332 COutlineHListBoxModel* listModel = (COutlineHListBoxModel*)iModel;
333 TInt originalIndex = CurrentItemIndex();
334 CHierListItem* itemPtr=listModel->Item(originalIndex);
335 TInt paragraphIndex = listModel->iOutlineMap->Index(itemPtr);
342 iView->SetCurrentItemIndex(0);
344 while (index < listModel->NumberOfItems() )
346 CArrayFix<CHierListItem*>* listArray=listModel->HierListArray();
347 if (!(*listArray)[index]->IsExpanded())
349 listModel->ExpandItemL(index);
350 CArrayFix<CHierListItem*>* newListArray=listModel->HierListArray();
352 item = listModel->GetItemByParagraph(paragraphIndex);
353 iView->SetCurrentItemIndex(item);
359 iView->CalcDataWidth();
360 iView->CalcBottomItemIndex();
362 item = listModel->GetItemByParagraph(paragraphIndex);
363 ((CHierarchicalListBoxView*)iView)->ScrollToMakeItemVisible(item);
364 ((CHierarchicalListBoxView*)iView)->DrawFromItem(iView->TopItemIndex());
367 ReportListBoxEventL(MEikListBoxObserver::EEventItemActioned);
369 eikonEnv->BusyMsgCancel();
373 void COutlineHListBox::CollapseAllItemsL()
376 CEikonEnv* eikonEnv=CEikonEnv::Static();
377 eikonEnv->BusyMsgL(R_WORD_COLLAPSE_OUTLINE, KWaitingTime);
379 COutlineHListBoxModel* listModel = (COutlineHListBoxModel*)iModel;
380 TInt originalIndex = CurrentItemIndex();
381 CHierListItem* itemPtr=listModel->Item(originalIndex);
382 TInt paragraphIndex = listModel->iOutlineMap->Index(itemPtr);
384 //TInt itemCount = listModel->NumberOfItems();
388 // Get root parent of this node
394 while (whilecount<=paragraphIndex)
396 if (listModel->iOutlineTable->At(whilecount).iIsChild)
400 rootParent = whilecount;
402 if (listModel->iOutlineTable->At(whilecount).iLastEntry)
410 while (index < listModel->NumberOfItems() )
412 CArrayFix<CHierListItem*>* listArray=listModel->HierListArray();
413 if ((*listArray)[index]->IsExpanded())
415 HlModel()->CollapseItem(index);
418 item = listModel->GetItemByParagraph(rootParent);
419 iView->SetCurrentItemIndex(item);
425 iView->CalcDataWidth();
426 iView->CalcBottomItemIndex();
428 item = listModel->GetItemByParagraph(paragraphIndex);
429 ((CHierarchicalListBoxView*)iView)->ScrollToMakeItemVisible(item);
430 ((CHierarchicalListBoxView*)iView)->DrawFromItem(iView->TopItemIndex());
433 ReportListBoxEventL(MEikListBoxObserver::EEventItemActioned);
435 eikonEnv->BusyMsgCancel();
442 // COutlineHListItemDrawer
443 //////////////////////////
445 COutlineHListItemDrawer::COutlineHListItemDrawer(COutlineHListBoxModel* aModel, const CFont* aFont, CArrayPtrFlat<CGulIcon>* aIcons)
446 : CHierarchicalListItemDrawer(aModel, aFont, aIcons)
449 CGulIcon* COutlineHListItemDrawer::ItemIcon(TInt aItemIndex) const
451 if (!iIconArray || aItemIndex <= -1 || aItemIndex >= iModel->NumberOfItems())
455 COutlineHListBoxModel* listModel = (COutlineHListBoxModel*)iModel;
456 CHierListItem* itemPtr = listModel->Item(aItemIndex);
457 TInt paragraphIndex = listModel->iOutlineMap->Index(itemPtr);
459 iconIndex = KClosedBitmapIndex;
461 if (paragraphIndex < listModel->iOutlineTable->Count() - 1)
463 if (listModel->iOutlineTable->At(paragraphIndex+1).iIsChild)
464 iconIndex = KExpandedBitmapIndex;
466 return (*iIconArray)[iconIndex];
470 // COutlineHListBoxView
471 ////////////////////////
474 TInt COutlineHListBoxView::GetParagraphLevel(CHierListItem* aItem) const
476 COutlineHListBoxModel* listModel = (COutlineHListBoxModel*)iModel;
477 TInt paragraphIndex = listModel->iOutlineMap->Index(aItem);
478 if (paragraphIndex != KErrNotFound)
479 return (listModel->iOutlineTable->At(paragraphIndex).iOutlineLevel);
485 void COutlineHListBoxView::DrawItem(TInt aItemIndex) const
487 // Modify this items level so that it is draw offset according to its doc level
489 COutlineHListBoxModel* listModel = (COutlineHListBoxModel*)iModel;
491 CHierListItem* itemToBeDrawn = listModel->Item(aItemIndex);
492 TInt paragraphLevel = GetParagraphLevel(itemToBeDrawn) - 1;
494 if (RedrawDisabled())
496 const TInt count = iModel->NumberOfItems();
498 if (aItemIndex >= 0 && aItemIndex < count && ItemIsVisible(aItemIndex))
500 iGc->SetClippingRect(iViewRect);
501 const TSize itemSize = ItemSize(aItemIndex, paragraphLevel);
502 iItemDrawer->SetItemCellSize(itemSize);
503 ClearPreceedingItemRect(aItemIndex, paragraphLevel);
504 const TPoint pos=ItemPos(aItemIndex, paragraphLevel);
505 TPoint markPos(iViewRect.iTl.iX, pos.iY);
506 iItemDrawer->DrawItemMark(ItemIsSelected(aItemIndex), iFlags & EDimmed,markPos);
508 DrawItemLinks(aItemIndex, paragraphLevel);
510 STATIC_CAST(CHierarchicalListItemDrawer*, iItemDrawer)->DrawActualItem(aItemIndex, TRect(pos,itemSize),
511 aItemIndex == iCurrentItemIndex, iFlags & EEmphasized, iFlags & EDimmed, ItemIsSelected(aItemIndex));
512 iGc->CancelClippingRect();
517 TSize COutlineHListBoxView::ItemSize(TInt aItemIndex, TInt aParagraphLevel) const
519 COutlineHListBoxModel* listModel = (COutlineHListBoxModel*)iModel;
521 if (! listModel->Item(aItemIndex))
523 const TInt indent=aParagraphLevel*KIndentPerLevel;
524 return TSize(Max(iViewRect.Width()-indent, DataWidth()), iItemHeight);
527 TPoint COutlineHListBoxView::ItemPos(TInt aItemIndex, TInt aParagraphLevel) const
529 // assumes aItemIndex is currently visible
531 COutlineHListBoxModel* listModel = (COutlineHListBoxModel*)iModel;
533 if (aItemIndex>-1 && aItemIndex<listModel->NumberOfItems())
534 indentLevel=aParagraphLevel;
535 TPoint pos(-iHScrollOffset + iViewRect.iTl.iX + indentLevel*KIndentPerLevel,
536 iViewRect.iTl.iY + (aItemIndex-iTopItemIndex)*iItemHeight);
540 void COutlineHListBoxView::ClearPreceedingItemRect(TInt aItemIndex, TInt aParagraphLevel) const
542 const TInt indentLevel=aParagraphLevel;
543 TPoint startPoint=ItemPos(aItemIndex, aParagraphLevel);
544 startPoint.iX-=indentLevel*KIndentPerLevel;
545 const TRect blankRect(startPoint,TPoint(startPoint.iX+indentLevel*KIndentPerLevel,startPoint.iY+iItemHeight));
546 iItemDrawer->ClearRect(blankRect);
550 void COutlineHListBoxView::DrawItemLinks(TInt aItemIndex, TInt aParagraphLevel) const
553 COutlineHListBoxModel* listModel = (COutlineHListBoxModel*)iModel;
555 CHierListItem* itemToBeDrawn=listModel->Item(aItemIndex);
556 const TInt itemLevel=itemToBeDrawn->Level();
559 TPoint startPoint=ItemPos(aItemIndex, itemLevel);
561 TInt parentLevel = itemLevel;
563 CHierListItem* parent = itemToBeDrawn->Parent();
566 parentLevel = GetParagraphLevel(parent);
567 startPoint=ItemPos(aItemIndex, parentLevel);
570 startPoint.iX-=KIndentPerLevel/2;
573 iGc->SetPenStyle(CGraphicsContext::ESolidPen);
577 const TPoint horizLineStart=startPoint+TPoint(0,iItemHeight/2);
578 iGc->MoveTo(horizLineStart);
579 iGc->DrawLineTo(TPoint(horizLineStart.iX+(KIndentPerLevel*(aParagraphLevel-parentLevel))+KIndentPerLevel/2,horizLineStart.iY));
583 TInt lineIndentLevel=itemLevel;
588 while (lineIndentLevel--)
592 if (lineIndentLevel+1<itemLevel)
594 parent=itemToBeDrawn->Parent();
597 TInt parentsToFind=count-1;
598 while (parentsToFind--)
599 parent=parent->Parent();
601 if (!(parent->HasFurtherSibling()))
603 parentLevel = GetParagraphLevel(parent);
604 startPoint=ItemPos(aItemIndex,parentLevel);
605 startPoint.iX-=KIndentPerLevel/2;
610 if (parent->Parent()) parent=parent->Parent();
611 parentLevel = GetParagraphLevel(parent);
612 startPoint=ItemPos(aItemIndex,parentLevel);
613 startPoint.iX-=KIndentPerLevel/2;
619 TInt vertLineLength=iItemHeight;
620 if (lineIndentLevel+1==itemLevel)
622 if (!itemToBeDrawn->HasFurtherSibling())
625 iGc->MoveTo(startPoint);
626 iGc->DrawLineTo(TPoint(startPoint.iX,startPoint.iY+vertLineLength));
628 startPoint.iX-=KIndentPerLevel;
637 // COutlineHListBoxModel
638 ////////////////////////
641 COutlineHListBoxModel* COutlineHListBoxModel::NewL(COutlineHListBox* aParent,CRichText* aText)
643 COutlineHListBoxModel* self = new (ELeave) COutlineHListBoxModel;
645 CleanupStack::PushL(self);
647 self->iParent=aParent;
656 void COutlineHListBoxModel::ConstructL()
658 iOutlineTable = new (ELeave)COutlineTable(2);
659 iOutlineMap=COutlineMap::NewL();
661 // Construct the Outline table from the document
666 COutlineHListBoxModel::~COutlineHListBoxModel()
670 delete iOutlineTable;
675 TInt COutlineHListBoxModel::CurrentCharPosition()
677 // This returns the character position in the document of the currently
678 // selected item in the listbox
680 // Get the current item's entry
681 TInt item = iParent->CurrentItemIndex();
683 CHierListItem* itemPtr=Item(item);
684 TInt paragraphIndex = iOutlineMap->Index(itemPtr);
686 return (iOutlineTable->At(paragraphIndex).iParagraphPos);
690 void COutlineHListBoxModel::CreateEntryTableL()
692 /* The scans through the document and creates the table which is then
693 used by the outline control.
694 Each entry in the table references one paragraph in the document that contains
695 an outline level greater than zero. (Only styles have outline levels).
696 For each of these paragraphs, the following information is stored:
697 Paragraph no. in the document,
698 Character position of start of paragraph, length of paragraph (or a maximum of
699 128 - used to generate the text of each node in the control),
700 the outline level of the paragraph.
701 Two boolean values are also stored:
702 isChild is True if the entry is the first child of a previous entry
703 lastEntry is True if this entry is the last entry at the current outline level
704 These two values are used to decide the structure of the tree
710 TInt paragraphLength=0;
712 TInt lastOutlineLevel = 0;
713 TBool isChild=EFalse;
714 // TBool lastEntry=ETrue;
715 TBool styleChanges=EFalse;
719 TInt paragraphCount = iText->ParagraphCount();
726 const CParaFormatLayer* paragraphStyle;
728 CEikonEnv* eikonEnv=CEikonEnv::Static();
730 eikonEnv->BusyMsgL(R_WORD_OUTLINE, KWaitingTime);
732 for (count=0; count<paragraphCount; count++)
734 // Get position of this paragraph
735 paragraphPos = iText->CharPosOfParagraph(paragraphLength, count);
736 if (paragraphLength>KMaxParagraphLength) paragraphLength=KMaxParagraphLength;
738 // Discard paragraphs with no text (length will be 1 because of paragraph delimiter)
739 if (paragraphLength>1)
741 paragraphStyle=iText->ParagraphStyle(styleChanges, paragraphPos, paragraphLength-1);
742 if (paragraphStyle->SenseBase())
744 outlineLevel=((CParagraphStyle*)paragraphStyle)->OutlineLevel();
747 isChild = (lastOutlineLevel < outlineLevel && lastOutlineLevel>0);
749 iOutlineTable->AppendL(TOutlineEntry(count,outlineLevel,paragraphLength-1,paragraphPos,isChild,EFalse));
751 lastOutlineLevel=outlineLevel;
760 // Now look through to find the final nodes at each level
766 for (count=1; count<entryCount-1; count++)
768 lastOutlineLevel = iOutlineTable->At(count).iOutlineLevel;
775 if (iOutlineTable->At(whileCount).iIsChild) childCount++;
776 if (iOutlineTable->At(whileCount).iLastEntry) childCount--;
777 if (childCount == 1) break;
780 // Check if this node is at the top level already
781 if (whileCount==0) continue;
782 else parentLevel = iOutlineTable->At(whileCount-1).iOutlineLevel;
784 whileCount = count+1;
786 while (whileCount<entryCount)
788 outlineLevel = iOutlineTable->At(whileCount).iOutlineLevel;
789 if (outlineLevel <= lastOutlineLevel && outlineLevel>parentLevel) break;
790 if (outlineLevel <= parentLevel)
792 iOutlineTable->At(count).iLastEntry = ETrue;
799 iOutlineTable->At(entryCount-1).iLastEntry = ETrue;
805 eikonEnv->BusyMsgCancel();
806 User::Leave(KErrNoOutline);
809 eikonEnv->BusyMsgCancel();
813 void COutlineHListBoxModel::ScanHeading(TDes& aText)
816 for (TInt pos=0; pos < aText.Length(); pos++)
817 // Replace this charater with a normal space
818 if (aText[pos] == CEditableText::ENonBreakingSpace)
822 void COutlineHListBoxModel::CreateRootListL()
824 // This creates entries in the list box for all entries in the outline
825 // table which are not children of any other nodes
827 iHierListArray=new(ELeave)CArrayFixSeg<CHierListItem*>(5);
834 TInt paragraphCount = iOutlineTable->Count();
836 TInt paragraphLength;
842 for (count=0; count<paragraphCount; count++)
844 paragraphPos= iOutlineTable->At(count).iParagraphPos;
845 paragraphLength= iOutlineTable->At(count).iParagraphLength;
846 lastEntry= iOutlineTable->At(count).iLastEntry;
847 isChild= iOutlineTable->At(count).iIsChild;
849 if (isChild) childCount++;
851 if (!isChild && childCount < 1)
853 iText->Extract(text, paragraphPos, paragraphLength);
856 item = new(ELeave)CHierListItem((TInt16)0);
857 CleanupStack::PushL(item);
858 item->SetTextL(text);
860 AddItemL(item, -1, -1);
861 iOutlineMap->BindL(count, item);
862 CleanupStack::Pop(); // Pop item
864 if (lastEntry) childCount--;
871 void COutlineHListBoxModel::ExpandItemL(TInt aItemIndex)
873 // This creates nodes for all immediate children of the given index
875 CHierListItem* itemToBeExpanded=Item(aItemIndex);
876 if (itemToBeExpanded->IsExpanded())
879 TInt newItemIndex = aItemIndex;
885 TInt paragraphCount = iOutlineTable->Count();
887 TInt paragraphLength;
893 index = iOutlineMap->Index(itemToBeExpanded);
896 if (index != KErrNotFound)
898 for (count=index+1; count<paragraphCount; count++)
900 lastEntry= iOutlineTable->At(count).iLastEntry;
901 isChild= iOutlineTable->At(count).iIsChild;
904 if (isChild) childCount++;
908 paragraphPos= iOutlineTable->At(count).iParagraphPos;
909 paragraphLength= iOutlineTable->At(count).iParagraphLength;
911 iText->Extract(text, paragraphPos, paragraphLength);
913 item = new(ELeave)CHierListItem((TInt16)0);
914 CleanupStack::PushL(item);
915 item->SetTextL(text);
917 AddItemL(item, aItemIndex, newItemIndex++);
919 iOutlineMap->BindL(count, item);
920 CleanupStack::Pop(); // pop item
921 itemToBeExpanded->SetExpanded();
923 if (lastEntry) childCount--;
924 if (childCount == 0) break;
931 TInt COutlineHListBoxModel::GetItemByParagraph(TInt aPara)
933 // Given a paragraph number in the Outline Table, this returns
934 // the item number in the list box.
936 CHierListItem* thisPtr = iOutlineMap->Ptr(aPara);
937 TInt size = HierListArray()->Count();
941 for (count=0; count<size; count++)
943 if (HierListArray()->At(count) == thisPtr)
953 TInt COutlineHListBoxModel::ExpandCurrentPositionL(TInt aCursorPos)
955 // This finds out which paragraph the cursor is currently at
956 // then expands its parents
958 TInt paragraphNo = iText->ParagraphNumberForPos(aCursorPos);
961 TInt paragraphCount = iOutlineTable->Count();
963 // Find out which style entry is above this position
965 for (count=0; count<paragraphCount; count++)
967 if (iOutlineTable->At(count).iParagraphNo > paragraphNo) break;
972 return (ExpandParagraphL(stylePara));
976 TInt COutlineHListBoxModel::ExpandParagraphL(TInt aPara)
978 // This looks to see if the paragraphs parent node is expand, and if not,
979 // expand it by recursion.
980 // The maximum iteration level is the number of levels deep the initial node is,
981 // and is unlikely to be more than 2 or 3 levels.
982 // The theoretical maximum is 99 levels, (as the UI only support entry of level 0-99)
985 // Check that this paragraph has not been expanded
987 if (iOutlineMap->IndexPresent(aPara) || aPara == -1) return GetItemByParagraph(aPara);
989 // If this node is a first child, then try to open the previous node
990 // since it must be it's parent
992 if (iOutlineTable->At(aPara).iIsChild)
994 ExpandParagraphL(aPara-1);
995 // Node aPara-1 is now guaranteed to exist, so open it up
996 TInt item = GetItemByParagraph(aPara-1);
998 if (item != -1) ExpandItemL(item);
1000 return GetItemByParagraph(aPara);
1004 // Need to look a bit further up since this node has siblings
1006 TInt childCount = 0;
1007 TInt para = aPara - 1;
1012 if (iOutlineTable->At(para).iLastEntry) childCount++;
1013 child = iOutlineTable->At(para).iIsChild;
1015 if (child && childCount == 0)
1017 // para is a child of the same level, so open its parent
1018 ExpandParagraphL(para-1);
1019 TInt item = GetItemByParagraph(para-1);
1020 if (item != -1) ExpandItemL(item);
1021 return GetItemByParagraph(aPara);
1024 if (child) childCount--;