1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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
) :
26 m_nKeyProbability( nProbability
),
27 m_nHighestProbaInSubtree( 0 ),
39 void Node::removeChild(Node
*& pChild
)
41 const sal_Unicode cKey
= pChild
->m_cKey
;
50 if ( !isSeparatedlyHandled( cKey
) )
52 std::list
<Node
*>::iterator i
= m_lChildren
.begin();
53 while ( i
!= m_lChildren
.end() )
57 i
= m_lChildren
.erase( 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 );
78 pChild
= m_pHead
->newNode( this, cKey
);
82 pChild
->insertKey( sKey
, nProbability
);
86 m_nKeyProbability
+= nProbability
;
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] );
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 );
126 pChild
= m_pHead
->newNode( this, cKey
);
132 void Node::childHasChanged(Node
*pChild
, const int nProbability
, bool bAllowRemoval
)
134 if ( nProbability
> m_nHighestProbaInSubtree
)
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
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
;
192 if ( (*i
)->m_nKeyProbability
> nSuggest
)
194 nSuggest
= (*i
)->m_nKeyProbability
;
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
208 m_nHighestProbaInSubtree
= 0;
210 bNodeProbabilityChanged
= true;
214 Node
* Node::our_pNodeNullPointer
= NULL
;
216 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */