/* * Elimina un nodo del árbol. */ void DeleteString(int p) { int replacement; /* Si el nodo a borrar no está en el árbol, no hacemos nada. */ if ( tree[ p ].parent == UNUSED ) return; /* Si el nodo a borrar sólo tiene un hijo, hacemos una contracción del árbol. */ if ( tree[ p ].larger_child == UNUSED ) ContractNode( p, tree[ p ].smaller_child ); else if ( tree[ p ].smaller_child == UNUSED ) ContractNode( p, tree[ p ].larger_child ); /* Si el nodo a borrar tiene ambos descendientes. */ else { /* Localizamos el siguiente nodo más pequeño que el nodo que intentamos borrar. */ replacement = FindNextNode( p ); /* Eliminaos el siguiente nodo más pequeño del árbol. Nótese que el nodo "replacemente" nunca va a tener los dos descendientes, lo que evita entrar en más de un nivel de recursión. */ DeleteString( replacement ); /* Sustituimos el nodo que estamos intentanbo borrar por el que acabamos de localizar y eliminar el árbol. */ ReplaceNode( p, replacement ); } }
//把一段有父子关系的Tree部分移走 void MoveItem(HTREEITEM m_startItem, HTREEITEM pItem, HTREEITEM nItem) { //详见司晋新okee程序中的Ctestview类 CMainFrame * pFWnd = (CMainFrame *)AfxGetMainWnd(); CModelTree * pTreeView = (CModelTree *)pFWnd->m_wndSplitter1.GetPane(0,2); CTreeCtrl& m_ctlTree = pTreeView->GetTreeCtrl(); HTREEITEM Item,nextItem,m_tempParentItem,lItem,m_temppItem; int no; no=Get_No_In_TreeItem(m_startItem,pTreeView); Item=m_ctlTree.InsertItem(m_ctlTree.GetItemText(m_startItem),0,1,pItem,nItem); //fqz: 修改treeitem pTreeView->m_Tree.TreeItem[no]=Item; lItem=m_startItem;//m_startItem值在以下循环中不变 nItem=Item; pItem=Item; m_temppItem=pItem;//m_temppItem值不变 while(FindNextNode(lItem,nextItem)!=FALSE)//查找下一个Node { //如果nextItem的父亲或者父亲的父亲是m_startItem; BOOL isParent=FALSE; m_tempParentItem=nextItem; //得到在nextItem的父亲在m_startItem位置 int indent=GetOffSet(m_startItem,nextItem); pItem=m_startItem; if(indent>0)//如果存在间接父子关系 { pItem=m_temppItem; for(int i=1;i<=GetOffSetLength(m_startItem,m_ctlTree.GetParentItem(nextItem));i++) FindNextNode(pItem,pItem); } else if(indent==0)//如果m_startItem和nextItem存在直接父子关系 { pItem=m_temppItem; } else if(indent==-1) break; no=Get_No_In_TreeItem(nextItem,pTreeView); nItem=m_ctlTree.InsertItem(m_ctlTree.GetItemText(nextItem),0,1,pItem,nItem); //fqz: 修改treeitem pTreeView->m_Tree.TreeItem[no]=nItem; lItem=nextItem; } m_ctlTree.DeleteItem(m_startItem); }
//注意:要求startItem和Item有直接或者间接的父子关系 //返回为startItem和Item的之间距离 int GetOffSetLength(HTREEITEM startItem, HTREEITEM Item) { //使用前提:GetOffSet(HTREEITEM startItem, HTREEITEM Item)>=0 //返回值n表示Item为startItem第n个(下一个节点) CMainFrame * pFWnd = (CMainFrame *)AfxGetMainWnd(); CModelTree * pTreeView = (CModelTree *)pFWnd->m_wndSplitter1.GetPane(0,2); CTreeCtrl& m_ctltree = pTreeView->GetTreeCtrl(); int i=0; do { i++; FindNextNode(startItem,startItem); if(Item==startItem) return i; }while(startItem!=NULL); return -1; }
//---------------------------------------------------------------------------- // Удаление строки из двоичного дерева поиска void DeleteString ( int p) { int replacement; if (tree [p].parent == UNUSED) return; if (tree [p].larger_child == UNUSED) ContractNode ( p, tree [p].smaller_child); else if (tree [p].smaller_child == UNUSED) ContractNode ( p, tree [p].larger_child); else { replacement = FindNextNode (p); DeleteString (replacement); ReplaceNode ( p, replacement); } }
// aNode is not a text node. Find the first text node starting at aNode/aOffset // in a preorder DOM traversal. static nsIDOMNode* FindNextTextNode(nsIDOMNode* aNode, PRInt32 aOffset, nsIDOMNode* aRoot) { NS_PRECONDITION(aNode, "Null starting node?"); NS_ASSERTION(!IsTextNode(aNode), "FindNextTextNode should start with a non-text node"); nsIDOMNode* checkNode; // Need to start at the aOffset'th child nsCOMPtr<nsIDOMNode> child; aNode->GetFirstChild(getter_AddRefs(child)); while (child && aOffset > 0) { nsCOMPtr<nsIDOMNode> next; child->GetNextSibling(getter_AddRefs(next)); child.swap(next); --aOffset; } if (child) { checkNode = child; } else { // aOffset was beyond the end of the child list. // goto next node in a preorder DOM traversal. nsCOMPtr<nsIDOMNode> next; aNode->GetNextSibling(getter_AddRefs(next)); while (!next) { // Go up aNode->GetParentNode(getter_AddRefs(next)); if (next == aRoot || !next) { return nsnull; } aNode = next; aNode->GetNextSibling(getter_AddRefs(next)); } checkNode = next; } while (checkNode && !IsTextNode(checkNode)) { checkNode = FindNextNode(checkNode, aRoot); } return checkNode; }
void mozInlineSpellWordUtil::BuildSoftText() { // First we have to work backwards from mSoftStart to find a text node // containing a DOM word separator, a non-inline-element // boundary, or the hard start node. That's where we'll start building the // soft string from. nsIDOMNode* node = mSoftBegin.mNode; PRInt32 firstOffsetInNode = 0; PRInt32 checkBeforeOffset = mSoftBegin.mOffset; while (node) { if (ContainsDOMWordSeparator(node, checkBeforeOffset, &firstOffsetInNode)) break; checkBeforeOffset = PR_INT32_MAX; if (IsBreakElement(mCSSView, node)) { // Since FindPrevNode follows tree *preorder*, we're about to traverse // up out of 'node'. Since node induces breaks (e.g., it's a block), // don't bother trying to look outside it, just stop now. break; } node = FindPrevNode(node, mRootNode); } // Now build up the string moving forward through the DOM until we reach // the soft end and *then* see a DOM word separator, a non-inline-element // boundary, or the hard end node. mSoftText.Truncate(); mSoftTextDOMMapping.Clear(); PRBool seenSoftEnd = PR_FALSE; // Leave this outside the loop so large heap string allocations can be reused // across iterations nsAutoString str; while (node) { if (node == mSoftEnd.mNode) { seenSoftEnd = PR_TRUE; } PRBool exit = PR_FALSE; if (IsTextNode(node)) { GetNodeText(node, str); PRInt32 lastOffsetInNode = str.Length(); if (seenSoftEnd) { // check whether we can stop after this for (PRInt32 i = node == mSoftEnd.mNode ? mSoftEnd.mOffset : 0; i < PRInt32(str.Length()); ++i) { if (IsDOMWordSeparator(str.CharAt(i))) { exit = PR_TRUE; // stop at the first separator after the soft end point lastOffsetInNode = i; break; } } } if (firstOffsetInNode < lastOffsetInNode) { PRInt32 len = lastOffsetInNode - firstOffsetInNode; mSoftTextDOMMapping.AppendElement( DOMTextMapping(NodeOffset(node, firstOffsetInNode), mSoftText.Length(), len)); mSoftText.Append(Substring(str, firstOffsetInNode, len)); } firstOffsetInNode = 0; } if (exit) break; CheckLeavingBreakElementClosure closure = { mCSSView, PR_FALSE }; node = FindNextNode(node, mRootNode, CheckLeavingBreakElement, &closure); if (closure.mLeftBreakElement || (node && IsBreakElement(mCSSView, node))) { // We left, or are entering, a break element (e.g., block). Maybe we can // stop now. if (seenSoftEnd) break; // Record the break mSoftText.Append(' '); } } #ifdef DEBUG_SPELLCHECK printf("Got DOM string: %s\n", NS_ConvertUTF16toUTF8(mSoftText).get()); #endif }