Version 4.0.2.1, tag libreoffice-4.0.2.1
[LibreOffice.git] / editeng / source / lookuptree / Node.cxx
blob2492a88e5c085a81ab41667f6db9be0c9786ca06
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <editeng/TreeHead.hxx>
21 #include <editeng/Node.hxx>
23 Node::Node(TreeHead* const pHead, Node* const pParent,
24 const sal_Unicode cKey, const int nProbability ) :
25 m_cKey( cKey ),
26 m_nKeyProbability( nProbability ),
27 m_nHighestProbaInSubtree( 0 ),
28 m_pParent( pParent ),
29 m_pSuggest( NULL ),
30 m_pHead( pHead ),
31 m_nChildren( 0 )
35 Node::~Node()
39 void Node::removeChild(Node*& pChild)
41 const sal_Unicode cKey = pChild->m_cKey;
43 if ( pChild )
45 delete pChild;
46 pChild = NULL;
47 --m_nChildren;
50 if ( !isSeparatedlyHandled( cKey ) )
52 std::list<Node*>::iterator i = m_lChildren.begin();
53 while ( i != m_lChildren.end() )
55 if ( !(*i) )
57 i = m_lChildren.erase( i );
59 else
61 ++i;
67 void Node::insertKey(OUString sKey, const int nProbability)
69 if ( !sKey.isEmpty() )
71 const sal_Unicode cKey = sKey[0];
72 sKey = sKey.copy( 1 );
74 Node*& pChild = getChildRef( cKey, true );
76 if ( !pChild )
78 pChild = m_pHead->newNode( this, cKey );
79 ++m_nChildren;
82 pChild->insertKey( sKey, nProbability );
84 else
86 m_nKeyProbability += nProbability;
87 if ( m_pParent )
89 // inform parent about change
90 int probability = m_nHighestProbaInSubtree > m_nKeyProbability ? m_nHighestProbaInSubtree : m_nKeyProbability;
91 m_pParent->childHasChanged( this, probability);
96 // Removes a complete keyword starting from this node of the tree.
97 void Node::removeKey(OUString sKey)
99 if ( !sKey.isEmpty() )
101 Node*& pChild = getChildRef( sKey[0] );
103 if ( pChild )
105 // recursive call downwards
106 pChild->removeKey( sKey.copy( 1 ) );
108 // Else: Keyword to be removed couldn't be found within the tree.
109 // No further changes are going to be made.
111 else // If we are the node to be removed...
113 // ... remove our entry from tree...
114 m_nKeyProbability = 0;
115 // ... and make sure our parent is updated.
116 m_pParent->childHasChanged( this, m_nHighestProbaInSubtree, this != m_pHead->m_pCurrent );
120 Node *Node::advanceKey(const sal_Unicode cKey)
122 Node*& pChild = getChildRef( cKey, true );
124 if ( !pChild )
126 pChild = m_pHead->newNode( this, cKey );
129 return pChild;
132 void Node::childHasChanged(Node *pChild, const int nProbability, bool bAllowRemoval)
134 if ( nProbability > m_nHighestProbaInSubtree )
136 m_pSuggest = pChild;
137 m_nHighestProbaInSubtree = nProbability;
139 if ( m_pParent ) // recursive call upwards
141 int probabilityChange = nProbability > m_nKeyProbability ? nProbability : m_nKeyProbability;
142 m_pParent->childHasChanged( this, probabilityChange );
145 else if ( !nProbability || nProbability < m_nHighestProbaInSubtree )
147 bool bNewEvaluationRequired = m_pSuggest == pChild;
149 if ( !nProbability && bAllowRemoval )
151 // Remove child. Caller needs to make sure we are allowed to.
152 removeChild( getChildRef( pChild->m_cKey ) );
155 if ( bNewEvaluationRequired )
157 // This is used to store whether we need to inform our parent about
158 // the changes within this node.
159 bool bNodeProbabilityChanged;
161 reevaluateSuggestion( bNodeProbabilityChanged );
163 // If necessary, inform our parent about change via recursive call
164 if ( bNodeProbabilityChanged && m_pParent )
166 bAllowRemoval = bAllowRemoval && this != m_pHead->m_pCurrent;
167 int probabilityChange = m_nHighestProbaInSubtree > m_nKeyProbability ? m_nHighestProbaInSubtree : m_nKeyProbability;
168 m_pParent->childHasChanged( this, probabilityChange, bAllowRemoval );
174 void Node::reevaluateSuggestion(bool& bNodeProbabilityChanged)
176 if ( m_nChildren ) // find child with highest probability
178 int nSuggest = 0;
179 Node* pSuggest = NULL;
181 // find child with highest probability in array
182 evaluateSeparateStorage( nSuggest, pSuggest );
184 // do the same thing within list
185 for ( std::list<Node*>::iterator i = m_lChildren.begin(); i != m_lChildren.end(); ++i )
187 if ( (*i)->m_nHighestProbaInSubtree > nSuggest )
189 nSuggest = (*i)->m_nHighestProbaInSubtree;
190 pSuggest = (*i);
192 if ( (*i)->m_nKeyProbability > nSuggest )
194 nSuggest = (*i)->m_nKeyProbability;
195 pSuggest = (*i);
199 // determine whether we need to inform our parent
200 bNodeProbabilityChanged = m_nHighestProbaInSubtree != nSuggest;
202 m_pSuggest = pSuggest;
203 m_nHighestProbaInSubtree = nSuggest;
205 else // there are no children
207 m_pSuggest = NULL;
208 m_nHighestProbaInSubtree = 0;
210 bNodeProbabilityChanged = true;
214 Node* Node::our_pNodeNullPointer = NULL;
216 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */