/*
 * 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 );
  }
}
Exemple #2
0
//把一段有父子关系的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);
}
Exemple #3
0
//注意:要求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;
}
Exemple #4
0
//----------------------------------------------------------------------------
// Удаление строки из двоичного дерева поиска 
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
}