LCOV - code coverage report
Current view: top level - starmath/source - visitors.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 130 1343 9.7 %
Date: 2012-08-25 Functions: 29 199 14.6 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 75 921 8.1 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*
       3                 :            :  * Version: MPL 1.1 / GPLv3+ / LGPLv3+
       4                 :            :  *
       5                 :            :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :            :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :            :  * the License. You may obtain a copy of the License at
       8                 :            :  * http://www.mozilla.org/MPL/
       9                 :            :  *
      10                 :            :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :            :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :            :  * for the specific language governing rights and limitations under the
      13                 :            :  * License.
      14                 :            :  *
      15                 :            :  * The Initial Developer of the Original Code is
      16                 :            :  *       Jonas Finnemann Jensen <jopsen@gmail.com>
      17                 :            :  * Portions created by the Initial Developer are Copyright (C) 2010 the
      18                 :            :  * Initial Developer. All Rights Reserved.
      19                 :            :  *
      20                 :            :  * Contributor(s): Jonas Finnemann Jensen <jopsen@gmail.com>
      21                 :            :  *
      22                 :            :  * Alternatively, the contents of this file may be used under the terms of
      23                 :            :  * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
      24                 :            :  * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
      25                 :            :  * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
      26                 :            :  * instead of those above.
      27                 :            :  */
      28                 :            : #include "visitors.hxx"
      29                 :            : #include "cursor.hxx"
      30                 :            : 
      31                 :            : ///////////////////////////////////// SmVisitorTest /////////////////////////////////////
      32                 :            : 
      33                 :          0 : void SmVisitorTest::Visit( SmTableNode* pNode )
      34                 :            : {
      35                 :            :     OSL_ENSURE( pNode->GetType( ) == NTABLE, "the visitor-patterns isn't implemented correctly" );
      36                 :          0 :     VisitChildren( pNode );
      37                 :          0 : }
      38                 :            : 
      39                 :          0 : void SmVisitorTest::Visit( SmBraceNode* pNode )
      40                 :            : {
      41                 :            :     OSL_ENSURE( pNode->GetType( ) == NBRACE, "the visitor-patterns isn't implemented correctly" );
      42                 :          0 :     VisitChildren( pNode );
      43                 :          0 : }
      44                 :            : 
      45                 :          0 : void SmVisitorTest::Visit( SmBracebodyNode* pNode )
      46                 :            : {
      47                 :            :     OSL_ENSURE( pNode->GetType( ) == NBRACEBODY, "the visitor-patterns isn't implemented correctly" );
      48                 :          0 :     VisitChildren( pNode );
      49                 :          0 : }
      50                 :            : 
      51                 :          0 : void SmVisitorTest::Visit( SmOperNode* pNode )
      52                 :            : {
      53                 :            :     OSL_ENSURE( pNode->GetType( ) == NOPER, "the visitor-patterns isn't implemented correctly" );
      54                 :          0 :     VisitChildren( pNode );
      55                 :          0 : }
      56                 :            : 
      57                 :          0 : void SmVisitorTest::Visit( SmAlignNode* pNode )
      58                 :            : {
      59                 :            :     OSL_ENSURE( pNode->GetType( ) == NALIGN, "the visitor-patterns isn't implemented correctly" );
      60                 :          0 :     VisitChildren( pNode );
      61                 :          0 : }
      62                 :            : 
      63                 :          0 : void SmVisitorTest::Visit( SmAttributNode* pNode )
      64                 :            : {
      65                 :            :     OSL_ENSURE( pNode->GetType( ) == NATTRIBUT, "the visitor-patterns isn't implemented correctly" );
      66                 :          0 :     VisitChildren( pNode );
      67                 :          0 : }
      68                 :            : 
      69                 :          0 : void SmVisitorTest::Visit( SmFontNode* pNode )
      70                 :            : {
      71                 :            :     OSL_ENSURE( pNode->GetType( ) == NFONT, "the visitor-patterns isn't implemented correctly" );
      72                 :          0 :     VisitChildren( pNode );
      73                 :          0 : }
      74                 :            : 
      75                 :          0 : void SmVisitorTest::Visit( SmUnHorNode* pNode )
      76                 :            : {
      77                 :            :     OSL_ENSURE( pNode->GetType( ) == NUNHOR, "the visitor-patterns isn't implemented correctly" );
      78                 :          0 :     VisitChildren( pNode );
      79                 :          0 : }
      80                 :            : 
      81                 :          0 : void SmVisitorTest::Visit( SmBinHorNode* pNode )
      82                 :            : {
      83                 :            :     OSL_ENSURE( pNode->GetType( ) == NBINHOR, "the visitor-patterns isn't implemented correctly" );
      84                 :          0 :     VisitChildren( pNode );
      85                 :          0 : }
      86                 :            : 
      87                 :          0 : void SmVisitorTest::Visit( SmBinVerNode* pNode )
      88                 :            : {
      89                 :            :     OSL_ENSURE( pNode->GetType( ) == NBINVER, "the visitor-patterns isn't implemented correctly" );
      90                 :          0 :     VisitChildren( pNode );
      91                 :          0 : }
      92                 :            : 
      93                 :          0 : void SmVisitorTest::Visit( SmBinDiagonalNode* pNode )
      94                 :            : {
      95                 :            :     OSL_ENSURE( pNode->GetType( ) == NBINDIAGONAL, "the visitor-patterns isn't implemented correctly" );
      96                 :          0 :     VisitChildren( pNode );
      97                 :          0 : }
      98                 :            : 
      99                 :          0 : void SmVisitorTest::Visit( SmSubSupNode* pNode )
     100                 :            : {
     101                 :            :     OSL_ENSURE( pNode->GetType( ) == NSUBSUP, "the visitor-patterns isn't implemented correctly" );
     102                 :          0 :     VisitChildren( pNode );
     103                 :          0 : }
     104                 :            : 
     105                 :          0 : void SmVisitorTest::Visit( SmMatrixNode* pNode )
     106                 :            : {
     107                 :            :     OSL_ENSURE( pNode->GetType( ) == NMATRIX, "the visitor-patterns isn't implemented correctly" );
     108                 :          0 :     VisitChildren( pNode );
     109                 :          0 : }
     110                 :            : 
     111                 :          0 : void SmVisitorTest::Visit( SmPlaceNode* pNode )
     112                 :            : {
     113                 :            :     OSL_ENSURE( pNode->GetType( ) == NPLACE, "the visitor-patterns isn't implemented correctly" );
     114                 :          0 :     VisitChildren( pNode );
     115                 :          0 : }
     116                 :            : 
     117                 :          0 : void SmVisitorTest::Visit( SmTextNode* pNode )
     118                 :            : {
     119                 :            :     OSL_ENSURE( pNode->GetType( ) == NTEXT, "the visitor-patterns isn't implemented correctly" );
     120                 :          0 :     VisitChildren( pNode );
     121                 :          0 : }
     122                 :            : 
     123                 :          0 : void SmVisitorTest::Visit( SmSpecialNode* pNode )
     124                 :            : {
     125                 :            :     OSL_ENSURE( pNode->GetType( ) == NSPECIAL, "the visitor-patterns isn't implemented correctly" );
     126                 :          0 :     VisitChildren( pNode );
     127                 :          0 : }
     128                 :            : 
     129                 :          0 : void SmVisitorTest::Visit( SmGlyphSpecialNode* pNode )
     130                 :            : {
     131                 :            :     OSL_ENSURE( pNode->GetType( ) == NGLYPH_SPECIAL, "the visitor-patterns isn't implemented correctly" );
     132                 :          0 :     VisitChildren( pNode );
     133                 :          0 : }
     134                 :            : 
     135                 :          0 : void SmVisitorTest::Visit( SmMathSymbolNode* pNode )
     136                 :            : {
     137                 :            :     OSL_ENSURE( pNode->GetType( ) == NMATH, "the visitor-patterns isn't implemented correctly" );
     138                 :          0 :     VisitChildren( pNode );
     139                 :          0 : }
     140                 :            : 
     141                 :          0 : void SmVisitorTest::Visit( SmBlankNode* pNode )
     142                 :            : {
     143                 :            :     OSL_ENSURE( pNode->GetType( ) == NBLANK, "the visitor-patterns isn't implemented correctly" );
     144                 :          0 :     VisitChildren( pNode );
     145                 :          0 : }
     146                 :            : 
     147                 :          0 : void SmVisitorTest::Visit( SmErrorNode* pNode )
     148                 :            : {
     149                 :            :     OSL_ENSURE( pNode->GetType( ) == NERROR, "the visitor-patterns isn't implemented correctly" );
     150                 :          0 :     VisitChildren( pNode );
     151                 :          0 : }
     152                 :            : 
     153                 :          0 : void SmVisitorTest::Visit( SmLineNode* pNode )
     154                 :            : {
     155                 :            :     OSL_ENSURE( pNode->GetType( ) == NLINE, "the visitor-patterns isn't implemented correctly" );
     156                 :          0 :     VisitChildren( pNode );
     157                 :          0 : }
     158                 :            : 
     159                 :          0 : void SmVisitorTest::Visit( SmExpressionNode* pNode )
     160                 :            : {
     161                 :            :     OSL_ENSURE( pNode->GetType( ) == NEXPRESSION, "the visitor-patterns isn't implemented correctly" );
     162                 :          0 :     VisitChildren( pNode );
     163                 :          0 : }
     164                 :            : 
     165                 :          0 : void SmVisitorTest::Visit( SmPolyLineNode* pNode )
     166                 :            : {
     167                 :            :     OSL_ENSURE( pNode->GetType( ) == NPOLYLINE, "the visitor-patterns isn't implemented correctly" );
     168                 :          0 :     VisitChildren( pNode );
     169                 :          0 : }
     170                 :            : 
     171                 :          0 : void SmVisitorTest::Visit( SmRootNode* pNode )
     172                 :            : {
     173                 :            :     OSL_ENSURE( pNode->GetType( ) == NROOT, "the visitor-patterns isn't implemented correctly" );
     174                 :          0 :     VisitChildren( pNode );
     175                 :          0 : }
     176                 :            : 
     177                 :          0 : void SmVisitorTest::Visit( SmRootSymbolNode* pNode )
     178                 :            : {
     179                 :            :     OSL_ENSURE( pNode->GetType( ) == NROOTSYMBOL, "the visitor-patterns isn't implemented correctly" );
     180                 :          0 :     VisitChildren( pNode );
     181                 :          0 : }
     182                 :            : 
     183                 :          0 : void SmVisitorTest::Visit( SmRectangleNode* pNode )
     184                 :            : {
     185                 :            :     OSL_ENSURE( pNode->GetType( ) == NRECTANGLE, "the visitor-patterns isn't implemented correctly" );
     186                 :          0 :     VisitChildren( pNode );
     187                 :          0 : }
     188                 :            : 
     189                 :          0 : void SmVisitorTest::Visit( SmVerticalBraceNode* pNode )
     190                 :            : {
     191                 :            :     OSL_ENSURE( pNode->GetType( ) == NVERTICAL_BRACE, "the visitor-patterns isn't implemented correctly" );
     192                 :          0 :     VisitChildren( pNode );
     193                 :          0 : }
     194                 :            : 
     195                 :          0 : void SmVisitorTest::VisitChildren( SmNode* pNode )
     196                 :            : {
     197         [ #  # ]:          0 :     SmNodeIterator it( pNode );
     198 [ #  # ][ #  # ]:          0 :     while( it.Next( ) )
     199         [ #  # ]:          0 :         it->Accept( this );
     200                 :          0 : }
     201                 :            : 
     202                 :            : /////////////////////////////// SmDefaultingVisitor ////////////////////////////////
     203                 :            : 
     204                 :          0 : void SmDefaultingVisitor::Visit( SmTableNode* pNode )
     205                 :            : {
     206                 :          0 :     DefaultVisit( pNode );
     207                 :          0 : }
     208                 :            : 
     209                 :          0 : void SmDefaultingVisitor::Visit( SmBraceNode* pNode )
     210                 :            : {
     211                 :          0 :     DefaultVisit( pNode );
     212                 :          0 : }
     213                 :            : 
     214                 :          0 : void SmDefaultingVisitor::Visit( SmBracebodyNode* pNode )
     215                 :            : {
     216                 :          0 :     DefaultVisit( pNode );
     217                 :          0 : }
     218                 :            : 
     219                 :          0 : void SmDefaultingVisitor::Visit( SmOperNode* pNode )
     220                 :            : {
     221                 :          0 :     DefaultVisit( pNode );
     222                 :          0 : }
     223                 :            : 
     224                 :          0 : void SmDefaultingVisitor::Visit( SmAlignNode* pNode )
     225                 :            : {
     226                 :          0 :     DefaultVisit( pNode );
     227                 :          0 : }
     228                 :            : 
     229                 :          0 : void SmDefaultingVisitor::Visit( SmAttributNode* pNode )
     230                 :            : {
     231                 :          0 :     DefaultVisit( pNode );
     232                 :          0 : }
     233                 :            : 
     234                 :          0 : void SmDefaultingVisitor::Visit( SmFontNode* pNode )
     235                 :            : {
     236                 :          0 :     DefaultVisit( pNode );
     237                 :          0 : }
     238                 :            : 
     239                 :          0 : void SmDefaultingVisitor::Visit( SmUnHorNode* pNode )
     240                 :            : {
     241                 :          0 :     DefaultVisit( pNode );
     242                 :          0 : }
     243                 :            : 
     244                 :          0 : void SmDefaultingVisitor::Visit( SmBinHorNode* pNode )
     245                 :            : {
     246                 :          0 :     DefaultVisit( pNode );
     247                 :          0 : }
     248                 :            : 
     249                 :          0 : void SmDefaultingVisitor::Visit( SmBinVerNode* pNode )
     250                 :            : {
     251                 :          0 :     DefaultVisit( pNode );
     252                 :          0 : }
     253                 :            : 
     254                 :          0 : void SmDefaultingVisitor::Visit( SmBinDiagonalNode* pNode )
     255                 :            : {
     256                 :          0 :     DefaultVisit( pNode );
     257                 :          0 : }
     258                 :            : 
     259                 :          0 : void SmDefaultingVisitor::Visit( SmSubSupNode* pNode )
     260                 :            : {
     261                 :          0 :     DefaultVisit( pNode );
     262                 :          0 : }
     263                 :            : 
     264                 :          0 : void SmDefaultingVisitor::Visit( SmMatrixNode* pNode )
     265                 :            : {
     266                 :          0 :     DefaultVisit( pNode );
     267                 :          0 : }
     268                 :            : 
     269                 :          0 : void SmDefaultingVisitor::Visit( SmPlaceNode* pNode )
     270                 :            : {
     271                 :          0 :     DefaultVisit( pNode );
     272                 :          0 : }
     273                 :            : 
     274                 :          0 : void SmDefaultingVisitor::Visit( SmTextNode* pNode )
     275                 :            : {
     276                 :          0 :     DefaultVisit( pNode );
     277                 :          0 : }
     278                 :            : 
     279                 :          0 : void SmDefaultingVisitor::Visit( SmSpecialNode* pNode )
     280                 :            : {
     281                 :          0 :     DefaultVisit( pNode );
     282                 :          0 : }
     283                 :            : 
     284                 :          0 : void SmDefaultingVisitor::Visit( SmGlyphSpecialNode* pNode )
     285                 :            : {
     286                 :          0 :     DefaultVisit( pNode );
     287                 :          0 : }
     288                 :            : 
     289                 :          0 : void SmDefaultingVisitor::Visit( SmMathSymbolNode* pNode )
     290                 :            : {
     291                 :          0 :     DefaultVisit( pNode );
     292                 :          0 : }
     293                 :            : 
     294                 :          0 : void SmDefaultingVisitor::Visit( SmBlankNode* pNode )
     295                 :            : {
     296                 :          0 :     DefaultVisit( pNode );
     297                 :          0 : }
     298                 :            : 
     299                 :          0 : void SmDefaultingVisitor::Visit( SmErrorNode* pNode )
     300                 :            : {
     301                 :          0 :     DefaultVisit( pNode );
     302                 :          0 : }
     303                 :            : 
     304                 :          0 : void SmDefaultingVisitor::Visit( SmLineNode* pNode )
     305                 :            : {
     306                 :          0 :     DefaultVisit( pNode );
     307                 :          0 : }
     308                 :            : 
     309                 :          0 : void SmDefaultingVisitor::Visit( SmExpressionNode* pNode )
     310                 :            : {
     311                 :          0 :     DefaultVisit( pNode );
     312                 :          0 : }
     313                 :            : 
     314                 :          0 : void SmDefaultingVisitor::Visit( SmPolyLineNode* pNode )
     315                 :            : {
     316                 :          0 :     DefaultVisit( pNode );
     317                 :          0 : }
     318                 :            : 
     319                 :          0 : void SmDefaultingVisitor::Visit( SmRootNode* pNode )
     320                 :            : {
     321                 :          0 :     DefaultVisit( pNode );
     322                 :          0 : }
     323                 :            : 
     324                 :          0 : void SmDefaultingVisitor::Visit( SmRootSymbolNode* pNode )
     325                 :            : {
     326                 :          0 :     DefaultVisit( pNode );
     327                 :          0 : }
     328                 :            : 
     329                 :          0 : void SmDefaultingVisitor::Visit( SmRectangleNode* pNode )
     330                 :            : {
     331                 :          0 :     DefaultVisit( pNode );
     332                 :          0 : }
     333                 :            : 
     334                 :          0 : void SmDefaultingVisitor::Visit( SmVerticalBraceNode* pNode )
     335                 :            : {
     336                 :          0 :     DefaultVisit( pNode );
     337                 :          0 : }
     338                 :            : 
     339                 :            : /////////////////////////////// SmCaretDrawingVisitor ////////////////////////////////
     340                 :            : 
     341                 :          0 : SmCaretDrawingVisitor::SmCaretDrawingVisitor( OutputDevice& rDevice,
     342                 :            :                                              SmCaretPos position,
     343                 :            :                                              Point offset,
     344                 :            :                                              bool caretVisible )
     345                 :          0 :  : rDev( rDevice )
     346                 :            : {
     347                 :          0 :     pos = position;
     348                 :          0 :     Offset = offset;
     349                 :          0 :     isCaretVisible = caretVisible;
     350                 :            :     OSL_ENSURE( position.IsValid( ), "Cannot draw invalid position!" );
     351         [ #  # ]:          0 :     if( !position.IsValid( ) )
     352                 :          0 :         return;
     353                 :            : 
     354                 :            :     //Save device state
     355         [ #  # ]:          0 :     rDev.Push( PUSH_FONT | PUSH_MAPMODE | PUSH_LINECOLOR | PUSH_FILLCOLOR | PUSH_TEXTCOLOR );
     356                 :            : 
     357         [ #  # ]:          0 :     pos.pSelectedNode->Accept( this );
     358                 :            :     //Restore device state
     359         [ #  # ]:          0 :     rDev.Pop( );
     360                 :            : }
     361                 :            : 
     362                 :          0 : void SmCaretDrawingVisitor::Visit( SmTextNode* pNode )
     363                 :            : {
     364                 :          0 :     long i = pos.Index;
     365                 :            : 
     366         [ #  # ]:          0 :     rDev.SetFont( pNode->GetFont( ) );
     367                 :            : 
     368                 :            :     //Find the line
     369         [ #  # ]:          0 :     SmNode* pLine = SmCursor::FindTopMostNodeInLine( pNode );
     370                 :            : 
     371                 :            :     //Find coordinates
     372         [ #  # ]:          0 :     long left = pNode->GetLeft( ) + rDev.GetTextWidth( pNode->GetText( ), 0, i ) + Offset.X( );
     373                 :          0 :     long top = pLine->GetTop( ) + Offset.Y( );
     374         [ #  # ]:          0 :     long height = pLine->GetHeight( );
     375                 :          0 :     long left_line = pLine->GetLeft( ) + Offset.X( );
     376         [ #  # ]:          0 :     long right_line = pLine->GetRight( ) + Offset.X( );
     377                 :            : 
     378                 :            :     //Set color
     379         [ #  # ]:          0 :     rDev.SetLineColor( Color( COL_BLACK ) );
     380                 :            : 
     381         [ #  # ]:          0 :     if ( isCaretVisible ) {
     382                 :            :         //Draw vertical line
     383                 :          0 :         Point p1( left, top );
     384                 :          0 :         Point p2( left, top + height );
     385         [ #  # ]:          0 :         rDev.DrawLine( p1, p2 );
     386                 :            :     }
     387                 :            : 
     388                 :            :     //Underline the line
     389                 :          0 :     Point pLeft( left_line, top + height );
     390                 :          0 :     Point pRight( right_line, top + height );
     391         [ #  # ]:          0 :     rDev.DrawLine( pLeft, pRight );
     392                 :          0 : }
     393                 :            : 
     394                 :          0 : void SmCaretDrawingVisitor::DefaultVisit( SmNode* pNode )
     395                 :            : {
     396         [ #  # ]:          0 :     rDev.SetLineColor( Color( COL_BLACK ) );
     397                 :            : 
     398                 :            :     //Find the line
     399         [ #  # ]:          0 :     SmNode* pLine = SmCursor::FindTopMostNodeInLine( pNode );
     400                 :            : 
     401                 :            :     //Find coordinates
     402 [ #  # ][ #  # ]:          0 :     long left = pNode->GetLeft( ) + Offset.X( ) + ( pos.Index == 1 ? pNode->GetWidth( ) : 0 );
     403                 :          0 :     long top = pLine->GetTop( ) + Offset.Y( );
     404         [ #  # ]:          0 :     long height = pLine->GetHeight( );
     405                 :          0 :     long left_line = pLine->GetLeft( ) + Offset.X( );
     406         [ #  # ]:          0 :     long right_line = pLine->GetRight( ) + Offset.X( );
     407                 :            : 
     408                 :            :     //Set color
     409         [ #  # ]:          0 :     rDev.SetLineColor( Color( COL_BLACK ) );
     410                 :            : 
     411         [ #  # ]:          0 :     if ( isCaretVisible ) {
     412                 :            :         //Draw vertical line
     413                 :          0 :         Point p1( left, top );
     414                 :          0 :         Point p2( left, top + height );
     415         [ #  # ]:          0 :         rDev.DrawLine( p1, p2 );
     416                 :            :     }
     417                 :            : 
     418                 :            :     //Underline the line
     419                 :          0 :     Point pLeft( left_line, top + height );
     420                 :          0 :     Point pRight( right_line, top + height );
     421         [ #  # ]:          0 :     rDev.DrawLine( pLeft, pRight );
     422                 :          0 : }
     423                 :            : 
     424                 :            : /////////////////////////////// SmCaretPos2LineVisitor ////////////////////////////////
     425                 :            : 
     426                 :          0 : void SmCaretPos2LineVisitor::Visit( SmTextNode* pNode )
     427                 :            : {
     428                 :            :     //Save device state
     429                 :          0 :     pDev->Push( PUSH_FONT | PUSH_TEXTCOLOR );
     430                 :            : 
     431                 :          0 :     long i = pos.Index;
     432                 :            : 
     433                 :          0 :     pDev->SetFont( pNode->GetFont( ) );
     434                 :            : 
     435                 :            :     //Find coordinates
     436                 :          0 :     long left = pNode->GetLeft( ) + pDev->GetTextWidth( pNode->GetText( ), 0, i );
     437                 :          0 :     long top = pNode->GetTop( );
     438                 :          0 :     long height = pNode->GetHeight( );
     439                 :            : 
     440                 :          0 :     line = SmCaretLine( left, top, height );
     441                 :            : 
     442                 :            :     //Restore device state
     443                 :          0 :     pDev->Pop( );
     444                 :          0 : }
     445                 :            : 
     446                 :          0 : void SmCaretPos2LineVisitor::DefaultVisit( SmNode* pNode )
     447                 :            : {
     448                 :            :     //Vertical line ( code from SmCaretDrawingVisitor )
     449                 :          0 :     Point p1 = pNode->GetTopLeft( );
     450         [ #  # ]:          0 :     if( pos.Index == 1 )
     451         [ #  # ]:          0 :         p1.Move( pNode->GetWidth( ), 0 );
     452                 :            : 
     453         [ #  # ]:          0 :     line = SmCaretLine( p1.X( ), p1.Y( ), pNode->GetHeight( ) );
     454                 :          0 : }
     455                 :            : 
     456                 :            : /////////////////////////////// Nasty temporary device!!! ////////////////////////////////
     457                 :            : 
     458                 :            : #include <tools/gen.hxx>
     459                 :            : #include <tools/fract.hxx>
     460                 :            : #include <rtl/math.hxx>
     461                 :            : #include <tools/color.hxx>
     462                 :            : #include <vcl/metric.hxx>
     463                 :            : #include <vcl/lineinfo.hxx>
     464                 :            : #include <vcl/outdev.hxx>
     465                 :            : #include <sfx2/module.hxx>
     466                 :            : #include "symbol.hxx"
     467                 :            : #include "smmod.hxx"
     468                 :            : 
     469                 :            : class SmTmpDevice2
     470                 :            : {
     471                 :            :     OutputDevice  &rOutDev;
     472                 :            : 
     473                 :            :     // disallow use of copy-constructor and assignment-operator
     474                 :            :     SmTmpDevice2( const SmTmpDevice2 &rTmpDev );
     475                 :            :     SmTmpDevice2 & operator = ( const SmTmpDevice2 &rTmpDev );
     476                 :            : 
     477                 :            :     Color   Impl_GetColor( const Color& rColor );
     478                 :            : 
     479                 :            : public:
     480                 :            :     SmTmpDevice2( OutputDevice &rTheDev, bool bUseMap100th_mm );
     481                 :      65803 :     ~SmTmpDevice2( )  { rOutDev.Pop( ); }
     482                 :            : 
     483                 :            :     void SetFont( const Font &rNewFont );
     484                 :            : 
     485         [ #  # ]:          0 :     void SetLineColor( const Color& rColor )    { rOutDev.SetLineColor( Impl_GetColor( rColor ) ); }
     486         [ +  - ]:       3648 :     void SetFillColor( const Color& rColor )    { rOutDev.SetFillColor( Impl_GetColor( rColor ) ); }
     487                 :            :     void SetTextColor( const Color& rColor )    { rOutDev.SetTextColor( Impl_GetColor( rColor ) ); }
     488                 :            : 
     489                 :            :     operator OutputDevice & ( ) const { return rOutDev; }
     490                 :            : };
     491                 :            : 
     492                 :      65803 : SmTmpDevice2::SmTmpDevice2( OutputDevice &rTheDev, bool bUseMap100th_mm ) :
     493                 :      65803 :     rOutDev( rTheDev )
     494                 :            : {
     495                 :            :     rOutDev.Push( PUSH_FONT | PUSH_MAPMODE |
     496                 :      65803 :                   PUSH_LINECOLOR | PUSH_FILLCOLOR | PUSH_TEXTCOLOR );
     497 [ -  + ][ -  + ]:      65803 :     if ( bUseMap100th_mm  &&  MAP_100TH_MM != rOutDev.GetMapMode( ).GetMapUnit( ) )
                 [ +  + ]
     498                 :            :     {
     499                 :            :         OSL_FAIL( "incorrect MapMode?" );
     500         [ #  # ]:          0 :         rOutDev.SetMapMode( MAP_100TH_MM );     //format for 100% always
     501                 :            :     }
     502                 :      65803 : }
     503                 :            : 
     504                 :      69451 : Color SmTmpDevice2::Impl_GetColor( const Color& rColor )
     505                 :            : {
     506                 :      69451 :     ColorData nNewCol = rColor.GetColor( );
     507         [ +  + ]:      69451 :     if ( COL_AUTO == nNewCol )
     508                 :            :     {
     509         [ -  + ]:      68875 :         if ( OUTDEV_PRINTER == rOutDev.GetOutDevType( ) )
     510                 :          0 :             nNewCol = COL_BLACK;
     511                 :            :         else
     512                 :            :         {
     513         [ +  - ]:      68875 :             Color aBgCol( rOutDev.GetBackground( ).GetColor( ) );
     514         [ +  + ]:      68875 :             if ( OUTDEV_WINDOW == rOutDev.GetOutDevType( ) )
     515 [ +  - ][ +  - ]:         43 :                 aBgCol = ( ( Window & ) rOutDev ).GetDisplayBackground( ).GetColor( );
     516                 :            : 
     517 [ +  - ][ +  - ]:      68875 :             nNewCol = SM_MOD( )->GetColorConfig( ).GetColorValue( svtools::FONTCOLOR ).nColor;
                 [ +  - ]
     518                 :            : 
     519                 :      68875 :             Color aTmpColor( nNewCol );
     520 [ -  + ][ #  # ]:      68875 :             if ( aBgCol.IsDark( ) && aTmpColor.IsDark( ) )
         [ #  # ][ -  + ]
                 [ +  - ]
     521                 :          0 :                 nNewCol = COL_WHITE;
     522 [ +  - ][ +  - ]:      68875 :             else if ( aBgCol.IsBright( ) && aTmpColor.IsBright( ) )
         [ +  - ][ -  + ]
                 [ -  + ]
     523                 :      68875 :                 nNewCol = COL_BLACK;
     524                 :            :         }
     525                 :            :     }
     526                 :      69451 :     return Color( nNewCol );
     527                 :            : }
     528                 :            : 
     529                 :      65803 : void SmTmpDevice2::SetFont( const Font &rNewFont )
     530                 :            : {
     531                 :      65803 :     rOutDev.SetFont( rNewFont );
     532         [ +  - ]:      65803 :     rOutDev.SetTextColor( Impl_GetColor( rNewFont.GetColor( ) ) );
     533                 :      65803 : }
     534                 :            : 
     535                 :            : /////////////////////////////// SmDrawingVisitor ////////////////////////////////
     536                 :            : 
     537                 :       7719 : void SmDrawingVisitor::Visit( SmTableNode* pNode )
     538                 :            : {
     539                 :       7719 :     DrawChildren( pNode );
     540                 :       7719 : }
     541                 :            : 
     542                 :       4320 : void SmDrawingVisitor::Visit( SmBraceNode* pNode )
     543                 :            : {
     544                 :       4320 :     DrawChildren( pNode );
     545                 :       4320 : }
     546                 :            : 
     547                 :       4320 : void SmDrawingVisitor::Visit( SmBracebodyNode* pNode )
     548                 :            : {
     549                 :       4320 :     DrawChildren( pNode );
     550                 :       4320 : }
     551                 :            : 
     552                 :       1353 : void SmDrawingVisitor::Visit( SmOperNode* pNode )
     553                 :            : {
     554                 :       1353 :     DrawChildren( pNode );
     555                 :       1353 : }
     556                 :            : 
     557                 :          0 : void SmDrawingVisitor::Visit( SmAlignNode* pNode )
     558                 :            : {
     559                 :          0 :     DrawChildren( pNode );
     560                 :          0 : }
     561                 :            : 
     562                 :       2693 : void SmDrawingVisitor::Visit( SmAttributNode* pNode )
     563                 :            : {
     564                 :       2693 :     DrawChildren( pNode );
     565                 :       2693 : }
     566                 :            : 
     567                 :          0 : void SmDrawingVisitor::Visit( SmFontNode* pNode )
     568                 :            : {
     569                 :          0 :     DrawChildren( pNode );
     570                 :          0 : }
     571                 :            : 
     572                 :         96 : void SmDrawingVisitor::Visit( SmUnHorNode* pNode )
     573                 :            : {
     574                 :         96 :     DrawChildren( pNode );
     575                 :         96 : }
     576                 :            : 
     577                 :       7015 : void SmDrawingVisitor::Visit( SmBinHorNode* pNode )
     578                 :            : {
     579                 :       7015 :     DrawChildren( pNode );
     580                 :       7015 : }
     581                 :            : 
     582                 :       2688 : void SmDrawingVisitor::Visit( SmBinVerNode* pNode )
     583                 :            : {
     584                 :       2688 :     DrawChildren( pNode );
     585                 :       2688 : }
     586                 :            : 
     587                 :          0 : void SmDrawingVisitor::Visit( SmBinDiagonalNode* pNode )
     588                 :            : {
     589                 :          0 :     DrawChildren( pNode );
     590                 :          0 : }
     591                 :            : 
     592                 :       6240 : void SmDrawingVisitor::Visit( SmSubSupNode* pNode )
     593                 :            : {
     594                 :       6240 :     DrawChildren( pNode );
     595                 :       6240 : }
     596                 :            : 
     597                 :        192 : void SmDrawingVisitor::Visit( SmMatrixNode* pNode )
     598                 :            : {
     599                 :        192 :     DrawChildren( pNode );
     600                 :        192 : }
     601                 :            : 
     602                 :        576 : void SmDrawingVisitor::Visit( SmPlaceNode* pNode )
     603                 :            : {
     604                 :        576 :     DrawSpecialNode( pNode );
     605                 :        576 : }
     606                 :            : 
     607                 :      40438 : void SmDrawingVisitor::Visit( SmTextNode* pNode )
     608                 :            : {
     609                 :      40438 :     DrawTextNode( pNode );
     610                 :      40438 : }
     611                 :            : 
     612                 :          0 : void SmDrawingVisitor::Visit( SmSpecialNode* pNode )
     613                 :            : {
     614                 :          0 :     DrawSpecialNode( pNode );
     615                 :          0 : }
     616                 :            : 
     617                 :          0 : void SmDrawingVisitor::Visit( SmGlyphSpecialNode* pNode )
     618                 :            : {
     619                 :          0 :     DrawSpecialNode( pNode );
     620                 :          0 : }
     621                 :            : 
     622                 :      20661 : void SmDrawingVisitor::Visit( SmMathSymbolNode* pNode )
     623                 :            : {
     624                 :      20661 :     DrawSpecialNode( pNode );
     625                 :      20661 : }
     626                 :            : 
     627                 :          0 : void SmDrawingVisitor::Visit( SmBlankNode* pNode )
     628                 :            : {
     629                 :          0 :     DrawChildren( pNode );
     630                 :          0 : }
     631                 :            : 
     632                 :          0 : void SmDrawingVisitor::Visit( SmErrorNode* pNode )
     633                 :            : {
     634                 :          0 :     DrawSpecialNode( pNode );
     635                 :          0 : }
     636                 :            : 
     637                 :       6855 : void SmDrawingVisitor::Visit( SmLineNode* pNode )
     638                 :            : {
     639                 :       6855 :     DrawChildren( pNode );
     640                 :       6855 : }
     641                 :            : 
     642                 :      38343 : void SmDrawingVisitor::Visit( SmExpressionNode* pNode )
     643                 :            : {
     644                 :      38343 :     DrawChildren( pNode );
     645                 :      38343 : }
     646                 :            : 
     647                 :        576 : void SmDrawingVisitor::Visit( SmRootNode* pNode )
     648                 :            : {
     649                 :        576 :     DrawChildren( pNode );
     650                 :        576 : }
     651                 :            : 
     652                 :        384 : void SmDrawingVisitor::Visit( SmVerticalBraceNode* pNode )
     653                 :            : {
     654                 :        384 :     DrawChildren( pNode );
     655                 :        384 : }
     656                 :            : 
     657                 :        576 : void SmDrawingVisitor::Visit( SmRootSymbolNode* pNode )
     658                 :            : {
     659         [ +  - ]:        576 :     if ( pNode->IsPhantom( ) )
     660                 :        576 :         return;
     661                 :            : 
     662                 :            :     // draw root-sign itself
     663         [ +  - ]:        576 :     DrawSpecialNode( pNode );
     664                 :            : 
     665         [ +  - ]:        576 :     SmTmpDevice2  aTmpDev( ( OutputDevice & ) rDev, true );
     666 [ +  - ][ +  - ]:        576 :     aTmpDev.SetFillColor( pNode->GetFont( ).GetColor( ) );
     667         [ +  - ]:        576 :     rDev.SetLineColor( );
     668         [ +  - ]:        576 :     aTmpDev.SetFont( pNode->GetFont( ) );
     669                 :            : 
     670                 :            :     // since the width is always unscaled it corresponds ot the _original_
     671                 :            :     // _unscaled_ font height to be used, we use that to calculate the
     672                 :            :     // bar height. Thus it is independent of the arguments height.
     673                 :            :     // ( see display of sqrt QQQ versus sqrt stack{Q#Q#Q#Q} )
     674         [ +  - ]:        576 :     long nBarHeight = pNode->GetWidth( ) * 7L / 100L;
     675                 :        576 :     long nBarWidth = pNode->GetBodyWidth( ) + pNode->GetBorderWidth( );
     676         [ +  - ]:        576 :     Point aBarOffset( pNode->GetWidth( ), +pNode->GetBorderWidth( ) );
     677                 :        576 :     Point aBarPos( Position + aBarOffset );
     678                 :            : 
     679         [ +  - ]:        576 :     Rectangle  aBar( aBarPos, Size( nBarWidth, nBarHeight ) );
     680                 :            :     //! avoid GROWING AND SHRINKING of drawn rectangle when constantly
     681                 :            :     //! increasing zoomfactor.
     682                 :            :     //  This is done by shifting its output-position to a point that
     683                 :            :     //  corresponds exactly to a pixel on the output device.
     684 [ +  - ][ +  - ]:        576 :     Point  aDrawPos( rDev.PixelToLogic( rDev.LogicToPixel( aBar.TopLeft( ) ) ) );
     685                 :        576 :     aBar.SetPos( aDrawPos );
     686                 :            : 
     687 [ +  - ][ +  - ]:        576 :     rDev.DrawRect( aBar );
     688                 :            : }
     689                 :            : 
     690                 :          0 : void SmDrawingVisitor::Visit( SmPolyLineNode* pNode )
     691                 :            : {
     692         [ #  # ]:          0 :     if ( pNode->IsPhantom( ) )
     693                 :          0 :         return;
     694                 :            : 
     695         [ #  # ]:          0 :     long nBorderwidth = pNode->GetFont( ).GetBorderWidth( );
     696                 :            : 
     697         [ #  # ]:          0 :     LineInfo  aInfo;
     698         [ #  # ]:          0 :     aInfo.SetWidth( pNode->GetWidth( ) - 2 * nBorderwidth );
     699                 :            : 
     700         [ #  # ]:          0 :     Point aOffset ( Point( ) - pNode->GetPolygon( ).GetBoundRect( ).TopLeft( )
     701                 :          0 :                    + Point( nBorderwidth, nBorderwidth ) ),
     702                 :          0 :           aPos ( Position + aOffset );
     703         [ #  # ]:          0 :     pNode->GetPolygon( ).Move( aPos.X( ), aPos.Y( ) );    //Works because Polygon wraps a pointer
     704                 :            : 
     705         [ #  # ]:          0 :     SmTmpDevice2  aTmpDev ( ( OutputDevice & ) rDev, false );
     706 [ #  # ][ #  # ]:          0 :     aTmpDev.SetLineColor( pNode->GetFont( ).GetColor( ) );
     707                 :            : 
     708 [ #  # ][ #  # ]:          0 :     rDev.DrawPolyLine( pNode->GetPolygon( ), aInfo );
                 [ #  # ]
     709                 :            : }
     710                 :            : 
     711                 :       3072 : void SmDrawingVisitor::Visit( SmRectangleNode* pNode )
     712                 :            : {
     713         [ +  - ]:       3072 :     if ( pNode->IsPhantom( ) )
     714                 :       3072 :         return;
     715                 :            : 
     716         [ +  - ]:       3072 :     SmTmpDevice2  aTmpDev ( ( OutputDevice & ) rDev, false );
     717 [ +  - ][ +  - ]:       3072 :     aTmpDev.SetFillColor( pNode->GetFont( ).GetColor( ) );
     718         [ +  - ]:       3072 :     rDev.SetLineColor( );
     719         [ +  - ]:       3072 :     aTmpDev.SetFont( pNode->GetFont( ) );
     720                 :            : 
     721         [ +  - ]:       3072 :     sal_uLong  nTmpBorderWidth = pNode->GetFont( ).GetBorderWidth( );
     722                 :            : 
     723                 :            :     // get rectangle and remove borderspace
     724 [ +  - ][ +  - ]:       3072 :     Rectangle  aTmp ( pNode->AsRectangle( ) + Position - pNode->GetTopLeft( ) );
                 [ +  - ]
     725                 :       3072 :     aTmp.Left( )   += nTmpBorderWidth;
     726                 :       3072 :     aTmp.Right( )  -= nTmpBorderWidth;
     727                 :       3072 :     aTmp.Top( )    += nTmpBorderWidth;
     728                 :       3072 :     aTmp.Bottom( ) -= nTmpBorderWidth;
     729                 :            : 
     730                 :            :     OSL_ENSURE( aTmp.GetHeight( ) > 0  &&  aTmp.GetWidth( ) > 0,
     731                 :            :                "Sm: leeres Rechteck" );
     732                 :            : 
     733                 :            :     //! avoid GROWING AND SHRINKING of drawn rectangle when constantly
     734                 :            :     //! increasing zoomfactor.
     735                 :            :     //  This is done by shifting its output-position to a point that
     736                 :            :     //  corresponds exactly to a pixel on the output device.
     737 [ +  - ][ +  - ]:       3072 :     Point  aPos ( rDev.PixelToLogic( rDev.LogicToPixel( aTmp.TopLeft( ) ) ) );
     738                 :       3072 :     aTmp.SetPos( aPos );
     739                 :            : 
     740 [ +  - ][ +  - ]:       3072 :     rDev.DrawRect( aTmp );
     741                 :            : }
     742                 :            : 
     743                 :      62251 : void SmDrawingVisitor::DrawTextNode( SmTextNode* pNode )
     744                 :            : {
     745 [ +  - ][ +  + ]:      62251 :     if ( pNode->IsPhantom( )  ||  pNode->GetText( ).Len( ) == 0  ||  pNode->GetText( ).GetChar( 0 ) == xub_Unicode( '\0' ) )
         [ -  + ][ +  + ]
     746                 :      62251 :         return;
     747                 :            : 
     748         [ +  - ]:      62155 :     SmTmpDevice2  aTmpDev ( ( OutputDevice & ) rDev, false );
     749         [ +  - ]:      62155 :     aTmpDev.SetFont( pNode->GetFont( ) );
     750                 :            : 
     751                 :      62155 :     Point  aPos ( Position );
     752         [ +  - ]:      62155 :     aPos.Y( ) += pNode->GetBaselineOffset( );
     753                 :            :     // auf Pixelkoordinaten runden
     754 [ +  - ][ +  - ]:      62155 :     aPos = rDev.PixelToLogic( rDev.LogicToPixel( aPos ) );
     755                 :            : 
     756 [ +  - ][ +  - ]:      62251 :     rDev.DrawStretchText( aPos, pNode->GetWidth( ), pNode->GetText( ) );
                 [ +  - ]
     757                 :            : }
     758                 :            : 
     759                 :      21813 : void SmDrawingVisitor::DrawSpecialNode( SmSpecialNode* pNode )
     760                 :            : {
     761                 :            :     //! since this chars might come from any font, that we may not have
     762                 :            :     //! set to ALIGN_BASELINE yet, we do it now.
     763                 :      21813 :     pNode->GetFont( ).SetAlign( ALIGN_BASELINE );
     764                 :            : 
     765                 :      21813 :     DrawTextNode( pNode );
     766                 :      21813 : }
     767                 :            : 
     768                 :      82794 : void SmDrawingVisitor::DrawChildren( SmNode* pNode )
     769                 :            : {
     770         [ +  - ]:      82794 :     if ( pNode->IsPhantom( ) )
     771                 :      82794 :         return;
     772                 :            : 
     773                 :      82794 :     Point rPosition = Position;
     774                 :            : 
     775         [ +  - ]:      82794 :     SmNodeIterator it( pNode );
     776 [ +  - ][ +  + ]:     224056 :     while( it.Next( ) )
     777                 :            :     {
     778                 :     141262 :         Point  aOffset ( it->GetTopLeft( ) - pNode->GetTopLeft( ) );
     779                 :     141262 :         Position = rPosition + aOffset;
     780         [ +  - ]:     141262 :         it->Accept( this );
     781                 :            :     }
     782                 :            : }
     783                 :            : 
     784                 :            : /////////////////////////////// SmSetSelectionVisitor ////////////////////////////////
     785                 :            : 
     786                 :          0 : SmSetSelectionVisitor::SmSetSelectionVisitor( SmCaretPos startPos, SmCaretPos endPos, SmNode* pTree) {
     787                 :          0 :     StartPos    = startPos;
     788                 :          0 :     EndPos      = endPos;
     789                 :          0 :     IsSelecting = false;
     790                 :            : 
     791                 :            :     //Assume that pTree is a SmTableNode
     792                 :            :     OSL_ENSURE(pTree->GetType() == NTABLE, "pTree should be a SmTableNode!");
     793                 :            :     //Visit root node, this is special as this node cannot be selected, but its children can!
     794         [ #  # ]:          0 :     if(pTree->GetType() == NTABLE){
     795                 :            :         //Change state if StartPos is in front of this node
     796 [ #  # ][ #  # ]:          0 :         if( StartPos.pSelectedNode == pTree && StartPos.Index == 0 )
     797                 :          0 :             IsSelecting = !IsSelecting;
     798                 :            :         //Change state if EndPos is in front of this node
     799 [ #  # ][ #  # ]:          0 :         if( EndPos.pSelectedNode == pTree && EndPos.Index == 0 )
     800                 :          0 :             IsSelecting = !IsSelecting;
     801                 :            :         OSL_ENSURE(!IsSelecting, "Caret positions needed to set IsSelecting about, shouldn't be possible!");
     802                 :            : 
     803                 :            :         //Visit lines
     804         [ #  # ]:          0 :         SmNodeIterator it( pTree );
     805 [ #  # ][ #  # ]:          0 :         while( it.Next( ) ) {
     806         [ #  # ]:          0 :             it->Accept( this );
     807                 :            :             //If we started a selection in this line and it haven't ended, we do that now!
     808         [ #  # ]:          0 :             if(IsSelecting) {
     809                 :          0 :                 IsSelecting = false;
     810         [ #  # ]:          0 :                 SetSelectedOnAll(it.Current(), true);
     811                 :            :                 //Set StartPos and EndPos to invalid positions, this ensures that an unused
     812                 :            :                 //start or end (because we forced end above), doesn't start a new selection.
     813                 :          0 :                 StartPos = EndPos = SmCaretPos();
     814                 :            :             }
     815                 :            :         }
     816                 :            :         //Check if pTree isn't selected
     817                 :            :         OSL_ENSURE(!pTree->IsSelected(), "pTree should never be selected!");
     818                 :            :         //Discard the selection if there's a bug (it's better than crashing)
     819         [ #  # ]:          0 :         if(pTree->IsSelected())
     820         [ #  # ]:          0 :             SetSelectedOnAll(pTree, false);
     821                 :            :     }else //This shouldn't happen, but I don't see any reason to die if it does
     822         [ #  # ]:          0 :         pTree->Accept(this);
     823                 :          0 : }
     824                 :            : 
     825                 :          0 : void SmSetSelectionVisitor::SetSelectedOnAll( SmNode* pSubTree, bool IsSelected ) {
     826                 :          0 :     pSubTree->SetSelected( IsSelected );
     827                 :            : 
     828                 :            :     //Quick BFS to set all selections
     829         [ #  # ]:          0 :     SmNodeIterator it( pSubTree );
     830 [ #  # ][ #  # ]:          0 :     while( it.Next( ) )
     831         [ #  # ]:          0 :         SetSelectedOnAll( it.Current( ), IsSelected );
     832                 :          0 : }
     833                 :            : 
     834                 :          0 : void SmSetSelectionVisitor::DefaultVisit( SmNode* pNode ) {
     835                 :            :     //Change state if StartPos is in front of this node
     836 [ #  # ][ #  # ]:          0 :     if( StartPos.pSelectedNode == pNode && StartPos.Index == 0 )
     837                 :          0 :         IsSelecting = !IsSelecting;
     838                 :            :     //Change state if EndPos is in front of this node
     839 [ #  # ][ #  # ]:          0 :     if( EndPos.pSelectedNode == pNode && EndPos.Index == 0 )
     840                 :          0 :         IsSelecting = !IsSelecting;
     841                 :            : 
     842                 :            :     //Cache current state
     843                 :          0 :     bool WasSelecting = IsSelecting;
     844                 :          0 :     bool ChangedState = false;
     845                 :            : 
     846                 :            :     //Set selected
     847                 :          0 :     pNode->SetSelected( IsSelecting );
     848                 :            : 
     849                 :            :     //Visit children
     850         [ #  # ]:          0 :     SmNodeIterator it( pNode );
     851 [ #  # ][ #  # ]:          0 :     while( it.Next( ) )
     852                 :            :     {
     853         [ #  # ]:          0 :         it->Accept( this );
     854 [ #  # ][ #  # ]:          0 :         ChangedState = ( WasSelecting != IsSelecting ) || ChangedState;
     855                 :            :     }
     856                 :            : 
     857                 :            :     //If state changed
     858         [ #  # ]:          0 :     if( ChangedState )
     859                 :            :     {
     860                 :            :         //Select this node and all of its children
     861                 :            :         //(Make exception for SmBracebodyNode)
     862   [ #  #  #  #  :          0 :         if( pNode->GetType() != NBRACEBODY ||
           #  # ][ #  # ]
     863                 :          0 :             !pNode->GetParent() ||
     864                 :          0 :             pNode->GetParent()->GetType() != NBRACE )
     865         [ #  # ]:          0 :             SetSelectedOnAll( pNode, true );
     866                 :            :         else
     867         [ #  # ]:          0 :             SetSelectedOnAll( pNode->GetParent(), true );
     868                 :            :         /* If the equation is:      sqrt{2 + 4} + 5
     869                 :            :          * And the selection is:    sqrt{2 + [4} +] 5
     870                 :            :          *      Where [ denotes StartPos and ] denotes EndPos
     871                 :            :          * Then the sqrt node should be selected, so that the
     872                 :            :          * effective selection is:  [sqrt{2 + 4} +] 5
     873                 :            :          * The same is the case if we swap StartPos and EndPos.
     874                 :            :          */
     875                 :            :     }
     876                 :            : 
     877                 :            :     //Change state if StartPos is after this node
     878 [ #  # ][ #  # ]:          0 :     if( StartPos.pSelectedNode == pNode && StartPos.Index == 1 )
     879                 :            :     {
     880                 :          0 :         IsSelecting = !IsSelecting;
     881                 :            :     }
     882                 :            :     //Change state if EndPos is after of this node
     883 [ #  # ][ #  # ]:          0 :     if( EndPos.pSelectedNode == pNode && EndPos.Index == 1 )
     884                 :            :     {
     885                 :          0 :         IsSelecting = !IsSelecting;
     886                 :            :     }
     887                 :          0 : }
     888                 :            : 
     889                 :          0 : void SmSetSelectionVisitor::VisitCompositionNode( SmNode* pNode ) {
     890                 :            :     //Change state if StartPos is in front of this node
     891 [ #  # ][ #  # ]:          0 :     if( StartPos.pSelectedNode == pNode && StartPos.Index == 0 )
     892                 :          0 :         IsSelecting = !IsSelecting;
     893                 :            :     //Change state if EndPos is in front of this node
     894 [ #  # ][ #  # ]:          0 :     if( EndPos.pSelectedNode == pNode && EndPos.Index == 0 )
     895                 :          0 :         IsSelecting = !IsSelecting;
     896                 :            : 
     897                 :            :     //Cache current state
     898                 :          0 :     bool WasSelecting = IsSelecting;
     899                 :            : 
     900                 :            :     //Visit children
     901         [ #  # ]:          0 :     SmNodeIterator it( pNode );
     902 [ #  # ][ #  # ]:          0 :     while( it.Next( ) )
     903         [ #  # ]:          0 :         it->Accept( this );
     904                 :            : 
     905                 :            :     //Set selected, if everything was selected
     906 [ #  # ][ #  # ]:          0 :     pNode->SetSelected( WasSelecting && IsSelecting );
     907                 :            : 
     908                 :            :     //Change state if StartPos is after this node
     909 [ #  # ][ #  # ]:          0 :     if( StartPos.pSelectedNode == pNode && StartPos.Index == 1 )
     910                 :          0 :         IsSelecting = !IsSelecting;
     911                 :            :     //Change state if EndPos is after of this node
     912 [ #  # ][ #  # ]:          0 :     if( EndPos.pSelectedNode == pNode && EndPos.Index == 1 )
     913                 :          0 :         IsSelecting = !IsSelecting;
     914                 :          0 : }
     915                 :            : 
     916                 :          0 : void SmSetSelectionVisitor::Visit( SmTextNode* pNode ) {
     917                 :          0 :     long    i1 = -1,
     918                 :          0 :             i2 = -1;
     919         [ #  # ]:          0 :     if( StartPos.pSelectedNode == pNode )
     920                 :          0 :         i1 = StartPos.Index;
     921         [ #  # ]:          0 :     if( EndPos.pSelectedNode == pNode )
     922                 :          0 :         i2 = EndPos.Index;
     923                 :            : 
     924                 :            :     long start, end;
     925                 :          0 :     pNode->SetSelected( true );
     926 [ #  # ][ #  # ]:          0 :     if( i1 != -1 && i2 != -1 ) {
     927         [ #  # ]:          0 :         start = i1 < i2 ? i1 : i2; //MIN
     928         [ #  # ]:          0 :         end   = i1 > i2 ? i1 : i2; //MAX
     929 [ #  # ][ #  # ]:          0 :     } else if( IsSelecting && i1 != -1 ) {
     930                 :          0 :         start = 0;
     931                 :          0 :         end = i1;
     932                 :          0 :         IsSelecting = false;
     933 [ #  # ][ #  # ]:          0 :     } else if( IsSelecting && i2 != -1 ) {
     934                 :          0 :         start = 0;
     935                 :          0 :         end = i2;
     936                 :          0 :         IsSelecting = false;
     937 [ #  # ][ #  # ]:          0 :     } else if( !IsSelecting && i1 != -1 ) {
     938                 :          0 :         start = i1;
     939                 :          0 :         end = pNode->GetText( ).Len( );
     940                 :          0 :         IsSelecting = true;
     941 [ #  # ][ #  # ]:          0 :     } else if( !IsSelecting && i2 != -1 ) {
     942                 :          0 :         start = i2;
     943                 :          0 :         end = pNode->GetText( ).Len( );
     944                 :          0 :         IsSelecting = true;
     945         [ #  # ]:          0 :     } else if( IsSelecting ) {
     946                 :          0 :         start = 0;
     947                 :          0 :         end = pNode->GetText( ).Len( );
     948                 :            :     } else {
     949                 :          0 :         pNode->SetSelected( false );
     950                 :          0 :         start = 0;
     951                 :          0 :         end = 0;
     952                 :            :     }
     953                 :          0 :     pNode->SetSelected( start != end );
     954                 :          0 :     pNode->SetSelectionStart( start );
     955                 :          0 :     pNode->SetSelectionEnd( end );
     956                 :          0 : }
     957                 :            : 
     958                 :          0 : void SmSetSelectionVisitor::Visit( SmExpressionNode* pNode ) {
     959                 :          0 :     VisitCompositionNode( pNode );
     960                 :          0 : }
     961                 :            : 
     962                 :          0 : void SmSetSelectionVisitor::Visit( SmLineNode* pNode ) {
     963                 :          0 :     VisitCompositionNode( pNode );
     964                 :          0 : }
     965                 :            : 
     966                 :          0 : void SmSetSelectionVisitor::Visit( SmAlignNode* pNode ) {
     967                 :          0 :     VisitCompositionNode( pNode );
     968                 :          0 : }
     969                 :            : 
     970                 :          0 : void SmSetSelectionVisitor::Visit( SmBinHorNode* pNode ) {
     971                 :          0 :     VisitCompositionNode( pNode );
     972                 :          0 : }
     973                 :            : 
     974                 :          0 : void SmSetSelectionVisitor::Visit( SmUnHorNode* pNode ) {
     975                 :          0 :     VisitCompositionNode( pNode );
     976                 :          0 : }
     977                 :            : 
     978                 :          0 : void SmSetSelectionVisitor::Visit( SmFontNode* pNode ) {
     979                 :          0 :     VisitCompositionNode( pNode );
     980                 :          0 : }
     981                 :            : 
     982                 :            : /////////////////////////////// SmCaretPosGraphBuildingVisitor ////////////////////////////////
     983                 :            : 
     984                 :          0 : SmCaretPosGraphBuildingVisitor::SmCaretPosGraphBuildingVisitor( SmNode* pRootNode ) {
     985                 :          0 :     pRightMost  = NULL;
     986         [ #  # ]:          0 :     pGraph = new SmCaretPosGraph( );
     987                 :            :     //pRootNode should always be a table
     988                 :            :     OSL_ENSURE( pRootNode->GetType( ) == NTABLE, "pRootNode must be a table node");
     989                 :            :     //Handle the special case where NTABLE is used a rootnode
     990         [ #  # ]:          0 :     if( pRootNode->GetType( ) == NTABLE ){
     991                 :            :         //Children are SmLineNodes
     992                 :            :         //Or so I thought... Aparently, the children can be instances of SmExpression
     993                 :            :         //especially if there's a error in the formula... So he we go, a simple work around.
     994         [ #  # ]:          0 :         SmNodeIterator it( pRootNode );
     995 [ #  # ][ #  # ]:          0 :         while( it.Next( ) ){
     996                 :            :             //There's a special invariant between this method and the Visit( SmLineNode* )
     997                 :            :             //Usually pRightMost may not be NULL, to avoid this pRightMost should here be
     998                 :            :             //set to a new SmCaretPos in front of it.Current( ), however, if it.Current( ) is
     999                 :            :             //an instance of SmLineNode we let SmLineNode create this position in front of
    1000                 :            :             //the visual line.
    1001                 :            :             //The argument for doing this is that we now don't have to worry about SmLineNode
    1002                 :            :             //being a visual line composition node. Thus, no need for yet another special case
    1003                 :            :             //in SmCursor::IsLineCompositionNode and everywhere this method is used.
    1004                 :            :             //if( it->GetType( ) != NLINE )
    1005         [ #  # ]:          0 :                 pRightMost = pGraph->Add( SmCaretPos( it.Current( ), 0 ) );
    1006         [ #  # ]:          0 :             it->Accept( this );
    1007                 :            :         }
    1008                 :            :     }else
    1009         [ #  # ]:          0 :         pRootNode->Accept(this);
    1010                 :          0 : }
    1011                 :            : 
    1012                 :          0 : void SmCaretPosGraphBuildingVisitor::Visit( SmLineNode* pNode ){
    1013         [ #  # ]:          0 :     SmNodeIterator it( pNode );
    1014 [ #  # ][ #  # ]:          0 :     while( it.Next( ) ){
    1015         [ #  # ]:          0 :         it->Accept( this );
    1016                 :            :     }
    1017                 :          0 : }
    1018                 :            : 
    1019                 :            : /** Build SmCaretPosGraph for SmTableNode
    1020                 :            :  * This method covers cases where SmTableNode is used in a binom or stack,
    1021                 :            :  * the special case where it is used as root node for the entire formula is
    1022                 :            :  * handled in the constructor.
    1023                 :            :  */
    1024                 :          0 : void SmCaretPosGraphBuildingVisitor::Visit( SmTableNode* pNode ){
    1025                 :          0 :     SmCaretPosGraphEntry *left  = pRightMost,
    1026         [ #  # ]:          0 :                          *right = pGraph->Add( SmCaretPos( pNode, 1) );
    1027                 :          0 :     bool bIsFirst = true;
    1028         [ #  # ]:          0 :     SmNodeIterator it( pNode );
    1029 [ #  # ][ #  # ]:          0 :     while( it.Next() ){
    1030         [ #  # ]:          0 :         pRightMost = pGraph->Add( SmCaretPos( it.Current(), 0 ), left);
    1031         [ #  # ]:          0 :         if(bIsFirst)
    1032                 :          0 :             left->SetRight(pRightMost);
    1033         [ #  # ]:          0 :         it->Accept( this );
    1034                 :          0 :         pRightMost->SetRight(right);
    1035         [ #  # ]:          0 :         if(bIsFirst)
    1036                 :          0 :             right->SetLeft(pRightMost);
    1037                 :          0 :         bIsFirst = false;
    1038                 :            :     }
    1039                 :          0 :     pRightMost = right;
    1040                 :          0 : }
    1041                 :            : 
    1042                 :            : /** Build SmCaretPosGraph for SmSubSupNode
    1043                 :            :  *
    1044                 :            :  * The child positions in a SubSupNode, where H is the body:
    1045                 :            :  * \code
    1046                 :            :  *      CSUP
    1047                 :            :  *
    1048                 :            :  * LSUP H  H RSUP
    1049                 :            :  *      H  H
    1050                 :            :  *      HHHH
    1051                 :            :  *      H  H
    1052                 :            :  * LSUB H  H RSUB
    1053                 :            :  *
    1054                 :            :  *      CSUB
    1055                 :            :  * \endcode
    1056                 :            :  *
    1057                 :            :  * Graph over these, where "left" is before the SmSubSupNode and "right" is after:
    1058                 :            :  * \dot
    1059                 :            :  *  digraph Graph{
    1060                 :            :  *      left -> H;
    1061                 :            :  *      H -> right;
    1062                 :            :  *      LSUP -> H;
    1063                 :            :  *      LSUB -> H;
    1064                 :            :  *      CSUP -> right;
    1065                 :            :  *      CSUB -> right;
    1066                 :            :  *      RSUP -> right;
    1067                 :            :  *      RSUB -> right;
    1068                 :            :  *  };
    1069                 :            :  * \enddot
    1070                 :            :  *
    1071                 :            :  */
    1072                 :          0 : void SmCaretPosGraphBuildingVisitor::Visit( SmSubSupNode* pNode )
    1073                 :            : {
    1074                 :            :     SmCaretPosGraphEntry *left,
    1075                 :            :                          *right,
    1076                 :            :                          *bodyLeft,
    1077                 :            :                          *bodyRight;
    1078                 :            : 
    1079                 :          0 :     left = pRightMost;
    1080                 :            :     OSL_ENSURE( pRightMost, "pRightMost shouldn't be NULL here!" );
    1081                 :            : 
    1082                 :            :     //Create bodyLeft
    1083                 :            :     OSL_ENSURE( pNode->GetBody( ), "SmSubSupNode Doesn't have a body!" );
    1084         [ #  # ]:          0 :     bodyLeft = pGraph->Add( SmCaretPos( pNode->GetBody( ), 0 ), left );
    1085                 :          0 :     left->SetRight( bodyLeft ); //TODO: Don't make this if LSUP or LSUB are NULL ( not sure??? )
    1086                 :            : 
    1087                 :            :     //Create right
    1088         [ #  # ]:          0 :     right = pGraph->Add( SmCaretPos( pNode, 1 ) );
    1089                 :            : 
    1090                 :            :     //Visit the body, to get bodyRight
    1091                 :          0 :     pRightMost = bodyLeft;
    1092                 :          0 :     pNode->GetBody( )->Accept( this );
    1093                 :          0 :     bodyRight = pRightMost;
    1094                 :          0 :     bodyRight->SetRight( right );
    1095                 :          0 :     right->SetLeft( bodyRight );
    1096                 :            : 
    1097                 :            :     SmNode* pChild;
    1098                 :            :     //If there's an LSUP
    1099         [ #  # ]:          0 :     if( ( pChild = pNode->GetSubSup( LSUP ) ) ){
    1100                 :            :         SmCaretPosGraphEntry *cLeft; //Child left
    1101         [ #  # ]:          0 :         cLeft = pGraph->Add( SmCaretPos( pChild, 0 ), left );
    1102                 :            : 
    1103                 :          0 :         pRightMost = cLeft;
    1104                 :          0 :         pChild->Accept( this );
    1105                 :            : 
    1106                 :          0 :         pRightMost->SetRight( bodyLeft );
    1107                 :            :     }
    1108                 :            :     //If there's an LSUB
    1109         [ #  # ]:          0 :     if( ( pChild = pNode->GetSubSup( LSUB ) ) ){
    1110                 :            :         SmCaretPosGraphEntry *cLeft; //Child left
    1111         [ #  # ]:          0 :         cLeft = pGraph->Add( SmCaretPos( pChild, 0 ), left );
    1112                 :            : 
    1113                 :          0 :         pRightMost = cLeft;
    1114                 :          0 :         pChild->Accept( this );
    1115                 :            : 
    1116                 :          0 :         pRightMost->SetRight( bodyLeft );
    1117                 :            :     }
    1118                 :            :     //If there's an CSUP
    1119         [ #  # ]:          0 :     if( ( pChild = pNode->GetSubSup( CSUP ) ) ){
    1120                 :            :         SmCaretPosGraphEntry *cLeft; //Child left
    1121         [ #  # ]:          0 :         cLeft = pGraph->Add( SmCaretPos( pChild, 0 ), left );
    1122                 :            : 
    1123                 :          0 :         pRightMost = cLeft;
    1124                 :          0 :         pChild->Accept( this );
    1125                 :            : 
    1126                 :          0 :         pRightMost->SetRight( right );
    1127                 :            :     }
    1128                 :            :     //If there's an CSUB
    1129         [ #  # ]:          0 :     if( ( pChild = pNode->GetSubSup( CSUB ) ) ){
    1130                 :            :         SmCaretPosGraphEntry *cLeft; //Child left
    1131         [ #  # ]:          0 :         cLeft = pGraph->Add( SmCaretPos( pChild, 0 ), left );
    1132                 :            : 
    1133                 :          0 :         pRightMost = cLeft;
    1134                 :          0 :         pChild->Accept( this );
    1135                 :            : 
    1136                 :          0 :         pRightMost->SetRight( right );
    1137                 :            :     }
    1138                 :            :     //If there's an RSUP
    1139         [ #  # ]:          0 :     if( ( pChild = pNode->GetSubSup( RSUP ) ) ){
    1140                 :            :         SmCaretPosGraphEntry *cLeft; //Child left
    1141         [ #  # ]:          0 :         cLeft = pGraph->Add( SmCaretPos( pChild, 0 ), bodyRight );
    1142                 :            : 
    1143                 :          0 :         pRightMost = cLeft;
    1144                 :          0 :         pChild->Accept( this );
    1145                 :            : 
    1146                 :          0 :         pRightMost->SetRight( right );
    1147                 :            :     }
    1148                 :            :     //If there's an RSUB
    1149         [ #  # ]:          0 :     if( ( pChild = pNode->GetSubSup( RSUB ) ) ){
    1150                 :            :         SmCaretPosGraphEntry *cLeft; //Child left
    1151         [ #  # ]:          0 :         cLeft = pGraph->Add( SmCaretPos( pChild, 0 ), bodyRight );
    1152                 :            : 
    1153                 :          0 :         pRightMost = cLeft;
    1154                 :          0 :         pChild->Accept( this );
    1155                 :            : 
    1156                 :          0 :         pRightMost->SetRight( right );
    1157                 :            :     }
    1158                 :            : 
    1159                 :            :     //Set return parameters
    1160                 :          0 :     pRightMost = right;
    1161                 :          0 : }
    1162                 :            : 
    1163                 :            : /** Build caret position for SmOperNode
    1164                 :            :  *
    1165                 :            :  * If first child is an SmSubSupNode we will ignore its
    1166                 :            :  * body, as this body is a SmMathSymbol, for SUM, INT or similar
    1167                 :            :  * that shouldn't be subject to modification.
    1168                 :            :  * If first child is not a SmSubSupNode, ignore it completely
    1169                 :            :  * as it is a SmMathSymbol.
    1170                 :            :  *
    1171                 :            :  * The child positions in a SmOperNode, where H is symbol, e.g. int, sum or similar:
    1172                 :            :  * \code
    1173                 :            :  *       TO
    1174                 :            :  *
    1175                 :            :  * LSUP H  H RSUP    BBB    BB  BBB  B   B
    1176                 :            :  *      H  H         B  B  B  B B  B  B B
    1177                 :            :  *      HHHH         BBB   B  B B  B   B
    1178                 :            :  *      H  H         B  B  B  B B  B   B
    1179                 :            :  * LSUB H  H RSUB    BBB    BB  BBB    B
    1180                 :            :  *
    1181                 :            :  *      FROM
    1182                 :            :  * \endcode
    1183                 :            :  * Notice, CSUP, etc. are actually granchildren, but inorder to ignore H, these are visited
    1184                 :            :  * from here. If they are present, that is if pOper is an instance of SmSubSupNode.
    1185                 :            :  *
    1186                 :            :  * Graph over these, where "left" is before the SmOperNode and "right" is after:
    1187                 :            :  * \dot
    1188                 :            :  *  digraph Graph{
    1189                 :            :  *      left -> BODY;
    1190                 :            :  *      BODY -> right;
    1191                 :            :  *      LSUP -> BODY;
    1192                 :            :  *      LSUB -> BODY;
    1193                 :            :  *      TO   -> BODY;
    1194                 :            :  *      FROM -> BODY;
    1195                 :            :  *      RSUP -> BODY;
    1196                 :            :  *      RSUB -> BODY;
    1197                 :            :  *  };
    1198                 :            :  * \enddot
    1199                 :            :  */
    1200                 :          0 : void SmCaretPosGraphBuildingVisitor::Visit( SmOperNode* pNode )
    1201                 :            : {
    1202                 :          0 :     SmNode *pOper = pNode->GetSubNode( 0 ),
    1203                 :          0 :            *pBody = pNode->GetSubNode( 1 );
    1204                 :            : 
    1205                 :          0 :     SmCaretPosGraphEntry *left = pRightMost,
    1206                 :            :                          *bodyLeft,
    1207                 :            :                          *bodyRight,
    1208                 :            :                          *right;
    1209                 :            :     //Create body left
    1210         [ #  # ]:          0 :     bodyLeft = pGraph->Add( SmCaretPos( pBody, 0 ), left );
    1211                 :          0 :     left->SetRight( bodyLeft );
    1212                 :            : 
    1213                 :            :     //Visit body, get bodyRight
    1214                 :          0 :     pRightMost = bodyLeft;
    1215                 :          0 :     pBody->Accept( this );
    1216                 :          0 :     bodyRight = pRightMost;
    1217                 :            : 
    1218                 :            :     //Create right
    1219         [ #  # ]:          0 :     right = pGraph->Add( SmCaretPos( pNode, 1 ), bodyRight );
    1220                 :          0 :     bodyRight->SetRight( right );
    1221                 :            : 
    1222                 :            :     //Get subsup pNode if any
    1223         [ #  # ]:          0 :     SmSubSupNode* pSubSup = pOper->GetType( ) == NSUBSUP ? ( SmSubSupNode* )pOper : NULL;
    1224                 :            : 
    1225                 :            :     SmNode* pChild;
    1226                 :            :     SmCaretPosGraphEntry *childLeft;
    1227 [ #  # ][ #  # ]:          0 :     if( pSubSup && ( pChild = pSubSup->GetSubSup( LSUP ) ) ) {
                 [ #  # ]
    1228                 :            :         //Create position in front of pChild
    1229         [ #  # ]:          0 :         childLeft = pGraph->Add( SmCaretPos( pChild, 0 ), left );
    1230                 :            :         //Visit pChild
    1231                 :          0 :         pRightMost = childLeft;
    1232                 :          0 :         pChild->Accept( this );
    1233                 :            :         //Set right on pRightMost from pChild
    1234                 :          0 :         pRightMost->SetRight( bodyLeft );
    1235                 :            :     }
    1236 [ #  # ][ #  # ]:          0 :     if( pSubSup && ( pChild = pSubSup->GetSubSup( LSUB ) ) ) {
                 [ #  # ]
    1237                 :            :         //Create position in front of pChild
    1238         [ #  # ]:          0 :         childLeft = pGraph->Add( SmCaretPos( pChild, 0 ), left );
    1239                 :            :         //Visit pChild
    1240                 :          0 :         pRightMost = childLeft;
    1241                 :          0 :         pChild->Accept( this );
    1242                 :            :         //Set right on pRightMost from pChild
    1243                 :          0 :         pRightMost->SetRight( bodyLeft );
    1244                 :            :     }
    1245 [ #  # ][ #  # ]:          0 :     if( pSubSup && ( pChild = pSubSup->GetSubSup( CSUP ) ) ) {//TO
                 [ #  # ]
    1246                 :            :         //Create position in front of pChild
    1247         [ #  # ]:          0 :         childLeft = pGraph->Add( SmCaretPos( pChild, 0 ), left );
    1248                 :            :         //Visit pChild
    1249                 :          0 :         pRightMost = childLeft;
    1250                 :          0 :         pChild->Accept( this );
    1251                 :            :         //Set right on pRightMost from pChild
    1252                 :          0 :         pRightMost->SetRight( bodyLeft );
    1253                 :            :     }
    1254 [ #  # ][ #  # ]:          0 :     if( pSubSup && ( pChild = pSubSup->GetSubSup( CSUB ) ) ) { //FROM
                 [ #  # ]
    1255                 :            :         //Create position in front of pChild
    1256         [ #  # ]:          0 :         childLeft = pGraph->Add( SmCaretPos( pChild, 0 ), left );
    1257                 :            :         //Visit pChild
    1258                 :          0 :         pRightMost = childLeft;
    1259                 :          0 :         pChild->Accept( this );
    1260                 :            :         //Set right on pRightMost from pChild
    1261                 :          0 :         pRightMost->SetRight( bodyLeft );
    1262                 :            :     }
    1263 [ #  # ][ #  # ]:          0 :     if( pSubSup && ( pChild = pSubSup->GetSubSup( RSUP ) ) ) {
                 [ #  # ]
    1264                 :            :         //Create position in front of pChild
    1265         [ #  # ]:          0 :         childLeft = pGraph->Add( SmCaretPos( pChild, 0 ), left );
    1266                 :            :         //Visit pChild
    1267                 :          0 :         pRightMost = childLeft;
    1268                 :          0 :         pChild->Accept( this );
    1269                 :            :         //Set right on pRightMost from pChild
    1270                 :          0 :         pRightMost->SetRight( bodyLeft );
    1271                 :            :     }
    1272 [ #  # ][ #  # ]:          0 :     if( pSubSup && ( pChild = pSubSup->GetSubSup( RSUB ) ) ) {
                 [ #  # ]
    1273                 :            :         //Create position in front of pChild
    1274         [ #  # ]:          0 :         childLeft = pGraph->Add( SmCaretPos( pChild, 0 ), left );
    1275                 :            :         //Visit pChild
    1276                 :          0 :         pRightMost = childLeft;
    1277                 :          0 :         pChild->Accept( this );
    1278                 :            :         //Set right on pRightMost from pChild
    1279                 :          0 :         pRightMost->SetRight( bodyLeft );
    1280                 :            :     }
    1281                 :            : 
    1282                 :            :     //Return right
    1283                 :          0 :     pRightMost = right;
    1284                 :          0 : }
    1285                 :            : 
    1286                 :          0 : void SmCaretPosGraphBuildingVisitor::Visit( SmMatrixNode* pNode )
    1287                 :            : {
    1288                 :          0 :     SmCaretPosGraphEntry *left  = pRightMost,
    1289         [ #  # ]:          0 :                          *right = pGraph->Add( SmCaretPos( pNode, 1 ) );
    1290                 :            : 
    1291         [ #  # ]:          0 :     for ( sal_uInt16 i = 0;  i < pNode->GetNumRows( ); i++ ) {
    1292                 :          0 :         SmCaretPosGraphEntry* r = left;
    1293         [ #  # ]:          0 :         for ( sal_uInt16 j = 0;  j < pNode->GetNumCols( ); j++ ){
    1294                 :          0 :             SmNode* pSubNode = pNode->GetSubNode( i * pNode->GetNumCols( ) + j );
    1295                 :            : 
    1296         [ #  # ]:          0 :             pRightMost = pGraph->Add( SmCaretPos( pSubNode, 0 ), r );
    1297 [ #  # ][ #  # ]:          0 :             if( j != 0 || ( pNode->GetNumRows( ) - 1 ) / 2 == i )
                 [ #  # ]
    1298                 :          0 :                 r->SetRight( pRightMost );
    1299                 :            : 
    1300                 :          0 :             pSubNode->Accept( this );
    1301                 :            : 
    1302                 :          0 :             r = pRightMost;
    1303                 :            :         }
    1304                 :          0 :         pRightMost->SetRight( right );
    1305         [ #  # ]:          0 :         if( ( pNode->GetNumRows( ) - 1 ) / 2 == i )
    1306                 :          0 :             right->SetLeft( pRightMost );
    1307                 :            :     }
    1308                 :            : 
    1309                 :          0 :     pRightMost = right;
    1310                 :          0 : }
    1311                 :            : 
    1312                 :            : /** Build SmCaretPosGraph for SmTextNode
    1313                 :            :  *
    1314                 :            :  * Lines in an SmTextNode:
    1315                 :            :  * \code
    1316                 :            :  * A B C
    1317                 :            :  * \endcode
    1318                 :            :  * Where A B and C are characters in the text.
    1319                 :            :  *
    1320                 :            :  * Graph over these, where "left" is before the SmTextNode and "right" is after:
    1321                 :            :  * \dot
    1322                 :            :  *  digraph Graph{
    1323                 :            :  *      left -> A;
    1324                 :            :  *      A -> B
    1325                 :            :  *      B -> right;
    1326                 :            :  *  };
    1327                 :            :  * \enddot
    1328                 :            :  * Notice that C and right is the same position here.
    1329                 :            :  */
    1330                 :          0 : void SmCaretPosGraphBuildingVisitor::Visit( SmTextNode* pNode )
    1331                 :            : {
    1332                 :            :     OSL_ENSURE( pNode->GetText( ).Len( ) > 0, "Empty SmTextNode is bad" );
    1333                 :            : 
    1334                 :          0 :     int size = pNode->GetText( ).Len( );
    1335         [ #  # ]:          0 :     for( int i = 1; i <= size; i++ ){
    1336                 :          0 :         SmCaretPosGraphEntry* pRight = pRightMost;
    1337         [ #  # ]:          0 :         pRightMost = pGraph->Add( SmCaretPos( pNode, i ), pRight );
    1338                 :          0 :         pRight->SetRight( pRightMost );
    1339                 :            :     }
    1340                 :          0 : }
    1341                 :            : 
    1342                 :            : /** Build SmCaretPosGraph for SmBinVerNode
    1343                 :            :  *
    1344                 :            :  * Lines in an SmBinVerNode:
    1345                 :            :  * \code
    1346                 :            :  *    A
    1347                 :            :  *  -----
    1348                 :            :  *    B
    1349                 :            :  * \endcode
    1350                 :            :  *
    1351                 :            :  * Graph over these, where "left" is before the SmBinVerNode and "right" is after:
    1352                 :            :  * \dot
    1353                 :            :  *  digraph Graph{
    1354                 :            :  *      left -> A;
    1355                 :            :  *      A -> right;
    1356                 :            :  *      B -> right;
    1357                 :            :  *  };
    1358                 :            :  * \enddot
    1359                 :            :  */
    1360                 :          0 : void SmCaretPosGraphBuildingVisitor::Visit( SmBinVerNode* pNode )
    1361                 :            : {
    1362                 :            :     //None if these children can be NULL, see SmBinVerNode::Arrange
    1363                 :          0 :     SmNode  *pNum   = pNode->GetSubNode( 0 ),
    1364                 :          0 :             *pDenom = pNode->GetSubNode( 2 );
    1365                 :            : 
    1366                 :            :     SmCaretPosGraphEntry *left,
    1367                 :            :                          *right,
    1368                 :            :                          *numLeft,
    1369                 :            :                          *denomLeft;
    1370                 :            : 
    1371                 :            :     //Set left
    1372                 :          0 :     left = pRightMost;
    1373                 :            :     OSL_ENSURE( pRightMost, "There must be a position in front of this" );
    1374                 :            : 
    1375                 :            :     //Create right
    1376         [ #  # ]:          0 :     right = pGraph->Add( SmCaretPos( pNode, 1 ) );
    1377                 :            : 
    1378                 :            :     //Create numLeft
    1379         [ #  # ]:          0 :     numLeft = pGraph->Add( SmCaretPos( pNum, 0 ), left );
    1380                 :          0 :     left->SetRight( numLeft );
    1381                 :            : 
    1382                 :            :     //Visit pNum
    1383                 :          0 :     pRightMost = numLeft;
    1384                 :          0 :     pNum->Accept( this );
    1385                 :          0 :     pRightMost->SetRight( right );
    1386                 :          0 :     right->SetLeft( pRightMost );
    1387                 :            : 
    1388                 :            :     //Create denomLeft
    1389         [ #  # ]:          0 :     denomLeft = pGraph->Add( SmCaretPos( pDenom, 0 ), left );
    1390                 :            : 
    1391                 :            :     //Visit pDenom
    1392                 :          0 :     pRightMost = denomLeft;
    1393                 :          0 :     pDenom->Accept( this );
    1394                 :          0 :     pRightMost->SetRight( right );
    1395                 :            : 
    1396                 :            :     //Set return parameter
    1397                 :          0 :     pRightMost = right;
    1398                 :          0 : }
    1399                 :            : 
    1400                 :            : /** Build SmCaretPosGraph for SmVerticalBraceNode
    1401                 :            :  *
    1402                 :            :  * Lines in an SmVerticalBraceNode:
    1403                 :            :  * \code
    1404                 :            :  *   pScript
    1405                 :            :  *  ________
    1406                 :            :  * /        \
    1407                 :            :  *   pBody
    1408                 :            :  * \endcode
    1409                 :            :  *
    1410                 :            :  */
    1411                 :          0 : void SmCaretPosGraphBuildingVisitor::Visit( SmVerticalBraceNode* pNode )
    1412                 :            : {
    1413                 :          0 :     SmNode  *pBody   = pNode->GetSubNode( 0 ),
    1414                 :          0 :             *pScript = pNode->GetSubNode( 2 );
    1415                 :            :     //None of these children can be NULL
    1416                 :            : 
    1417                 :            :     SmCaretPosGraphEntry  *left,
    1418                 :            :                         *bodyLeft,
    1419                 :            :                         *scriptLeft,
    1420                 :            :                         *right;
    1421                 :            : 
    1422                 :          0 :     left = pRightMost;
    1423                 :            : 
    1424                 :            :     //Create right
    1425         [ #  # ]:          0 :     right = pGraph->Add( SmCaretPos( pNode, 1 ) );
    1426                 :            : 
    1427                 :            :     //Create bodyLeft
    1428         [ #  # ]:          0 :     bodyLeft = pGraph->Add( SmCaretPos( pBody, 0 ), left );
    1429                 :          0 :     left->SetRight( bodyLeft );
    1430                 :          0 :     pRightMost = bodyLeft;
    1431                 :          0 :     pBody->Accept( this );
    1432                 :          0 :     pRightMost->SetRight( right );
    1433                 :          0 :     right->SetLeft( pRightMost );
    1434                 :            : 
    1435                 :            :     //Create script
    1436         [ #  # ]:          0 :     scriptLeft = pGraph->Add( SmCaretPos( pScript, 0 ), left );
    1437                 :          0 :     pRightMost = scriptLeft;
    1438                 :          0 :     pScript->Accept( this );
    1439                 :          0 :     pRightMost->SetRight( right );
    1440                 :            : 
    1441                 :            :     //Set return value
    1442                 :          0 :     pRightMost = right;
    1443                 :          0 : }
    1444                 :            : 
    1445                 :            : /** Build SmCaretPosGraph for SmBinDiagonalNode
    1446                 :            :  *
    1447                 :            :  * Lines in an SmBinDiagonalNode:
    1448                 :            :  * \code
    1449                 :            :  *  A /
    1450                 :            :  *   /
    1451                 :            :  *  / B
    1452                 :            :  * \endcode
    1453                 :            :  * Where A and B are lines.
    1454                 :            :  *
    1455                 :            :  * Used in formulas such as "A wideslash B"
    1456                 :            :  */
    1457                 :          0 : void SmCaretPosGraphBuildingVisitor::Visit( SmBinDiagonalNode* pNode )
    1458                 :            : {
    1459                 :          0 :     SmNode  *A = pNode->GetSubNode( 0 ),
    1460                 :          0 :             *B = pNode->GetSubNode( 1 );
    1461                 :            : 
    1462                 :            :     SmCaretPosGraphEntry  *left,
    1463                 :            :                         *leftA,
    1464                 :            :                         *rightA,
    1465                 :            :                         *leftB,
    1466                 :            :                         *right;
    1467                 :          0 :     left = pRightMost;
    1468                 :            : 
    1469                 :            :     //Create right
    1470         [ #  # ]:          0 :     right = pGraph->Add( SmCaretPos( pNode, 1 ) );
    1471                 :            : 
    1472                 :            :     //Create left A
    1473         [ #  # ]:          0 :     leftA = pGraph->Add( SmCaretPos( A, 0 ), left );
    1474                 :          0 :     left->SetRight( leftA );
    1475                 :            : 
    1476                 :            :     //Visit A
    1477                 :          0 :     pRightMost = leftA;
    1478                 :          0 :     A->Accept( this );
    1479                 :          0 :     rightA = pRightMost;
    1480                 :            : 
    1481                 :            :     //Create left B
    1482         [ #  # ]:          0 :     leftB = pGraph->Add( SmCaretPos( B, 0 ), rightA );
    1483                 :          0 :     rightA->SetRight( leftB );
    1484                 :            : 
    1485                 :            :     //Visit B
    1486                 :          0 :     pRightMost = leftB;
    1487                 :          0 :     B->Accept( this );
    1488                 :          0 :     pRightMost->SetRight( right );
    1489                 :          0 :     right->SetLeft( pRightMost );
    1490                 :            : 
    1491                 :            :     //Set return value
    1492                 :          0 :     pRightMost = right;
    1493                 :          0 : }
    1494                 :            : 
    1495                 :            : //Straigt forward ( I think )
    1496                 :          0 : void SmCaretPosGraphBuildingVisitor::Visit( SmBinHorNode* pNode )
    1497                 :            : {
    1498         [ #  # ]:          0 :     SmNodeIterator it( pNode );
    1499 [ #  # ][ #  # ]:          0 :     while( it.Next( ) )
    1500         [ #  # ]:          0 :         it->Accept( this );
    1501                 :          0 : }
    1502                 :          0 : void SmCaretPosGraphBuildingVisitor::Visit( SmUnHorNode* pNode )
    1503                 :            : {
    1504                 :            :     // Unary operator node
    1505         [ #  # ]:          0 :     SmNodeIterator it( pNode );
    1506 [ #  # ][ #  # ]:          0 :     while( it.Next( ) )
    1507         [ #  # ]:          0 :         it->Accept( this );
    1508                 :            : 
    1509                 :          0 : }
    1510                 :            : 
    1511                 :          0 : void SmCaretPosGraphBuildingVisitor::Visit( SmExpressionNode* pNode )
    1512                 :            : {
    1513         [ #  # ]:          0 :     SmNodeIterator it( pNode );
    1514 [ #  # ][ #  # ]:          0 :     while( it.Next( ) )
    1515         [ #  # ]:          0 :         it->Accept( this );
    1516                 :          0 : }
    1517                 :            : 
    1518                 :          0 : void SmCaretPosGraphBuildingVisitor::Visit( SmFontNode* pNode )
    1519                 :            : {
    1520                 :            :     //Has only got one child, should act as an expression if possible
    1521         [ #  # ]:          0 :     SmNodeIterator it( pNode );
    1522 [ #  # ][ #  # ]:          0 :     while( it.Next( ) )
    1523         [ #  # ]:          0 :         it->Accept( this );
    1524                 :          0 : }
    1525                 :            : 
    1526                 :            : /** Build SmCaretPosGraph for SmBracebodyNode
    1527                 :            :  * Acts as an SmExpressionNode
    1528                 :            :  *
    1529                 :            :  * Below is an example of a formula tree that has multiple children for SmBracebodyNode
    1530                 :            :  * \dot
    1531                 :            :  * digraph {
    1532                 :            :  * labelloc = "t";
    1533                 :            :  * label= "Equation: \"lbrace i mline i in setZ rbrace\"";
    1534                 :            :  * n0 [label="SmTableNode"];
    1535                 :            :  * n0 -> n1 [label="0"];
    1536                 :            :  * n1 [label="SmLineNode"];
    1537                 :            :  * n1 -> n2 [label="0"];
    1538                 :            :  * n2 [label="SmExpressionNode"];
    1539                 :            :  * n2 -> n3 [label="0"];
    1540                 :            :  * n3 [label="SmBraceNode"];
    1541                 :            :  * n3 -> n4 [label="0"];
    1542                 :            :  * n4 [label="SmMathSymbolNode: {"];
    1543                 :            :  * n3 -> n5 [label="1"];
    1544                 :            :  * n5 [label="SmBracebodyNode"];
    1545                 :            :  * n5 -> n6 [label="0"];
    1546                 :            :  * n6 [label="SmExpressionNode"];
    1547                 :            :  * n6 -> n7 [label="0"];
    1548                 :            :  * n7 [label="SmTextNode: i"];
    1549                 :            :  * n5 -> n8 [label="1"];
    1550                 :            :  * n8 [label="SmMathSymbolNode: ∣"];
    1551                 :            :  * n5 -> n9 [label="2"];
    1552                 :            :  * n9 [label="SmExpressionNode"];
    1553                 :            :  * n9 -> n10 [label="0"];
    1554                 :            :  * n10 [label="SmBinHorNode"];
    1555                 :            :  * n10 -> n11 [label="0"];
    1556                 :            :  * n11 [label="SmTextNode: i"];
    1557                 :            :  * n10 -> n12 [label="1"];
    1558                 :            :  * n12 [label="SmMathSymbolNode: ∈"];
    1559                 :            :  * n10 -> n13 [label="2"];
    1560                 :            :  * n13 [label="SmMathSymbolNode: ℤ"];
    1561                 :            :  * n3 -> n14 [label="2"];
    1562                 :            :  * n14 [label="SmMathSymbolNode: }"];
    1563                 :            :  * }
    1564                 :            :  * \enddot
    1565                 :            :  */
    1566                 :          0 : void SmCaretPosGraphBuildingVisitor::Visit( SmBracebodyNode* pNode )
    1567                 :            : {
    1568         [ #  # ]:          0 :     SmNodeIterator it( pNode );
    1569 [ #  # ][ #  # ]:          0 :     while( it.Next( ) ) {
    1570         [ #  # ]:          0 :         SmCaretPosGraphEntry* pStart = pGraph->Add( SmCaretPos( it.Current(), 0), pRightMost );
    1571                 :          0 :         pRightMost->SetRight( pStart );
    1572                 :          0 :         pRightMost = pStart;
    1573         [ #  # ]:          0 :         it->Accept( this );
    1574                 :            :     }
    1575                 :          0 : }
    1576                 :            : 
    1577                 :            : /** Build SmCaretPosGraph for SmAlignNode
    1578                 :            :  * Acts as an SmExpressionNode, as it only has one child this okay
    1579                 :            :  */
    1580                 :          0 : void SmCaretPosGraphBuildingVisitor::Visit( SmAlignNode* pNode )
    1581                 :            : {
    1582         [ #  # ]:          0 :     SmNodeIterator it( pNode );
    1583 [ #  # ][ #  # ]:          0 :     while( it.Next( ) )
    1584         [ #  # ]:          0 :         it->Accept( this );
    1585                 :          0 : }
    1586                 :            : 
    1587                 :            : /** Build SmCaretPosGraph for SmRootNode
    1588                 :            :  *
    1589                 :            :  * Lines in an SmRootNode:
    1590                 :            :  * \code
    1591                 :            :  *    _________
    1592                 :            :  *  A/
    1593                 :            :  * \/    B
    1594                 :            :  *
    1595                 :            :  * \endcode
    1596                 :            :  * A: pExtra ( optional, can be NULL ),
    1597                 :            :  * B: pBody
    1598                 :            :  *
    1599                 :            :  * Graph over these, where "left" is before the SmRootNode and "right" is after:
    1600                 :            :  * \dot
    1601                 :            :  *  digraph Graph{
    1602                 :            :  *      left -> B;
    1603                 :            :  *      B -> right;
    1604                 :            :  *      A -> B;
    1605                 :            :  *  }
    1606                 :            :  * \enddot
    1607                 :            :  */
    1608                 :          0 : void SmCaretPosGraphBuildingVisitor::Visit( SmRootNode* pNode )
    1609                 :            : {
    1610                 :          0 :     SmNode  *pExtra = pNode->GetSubNode( 0 ), //Argument, NULL for sqrt, and SmTextNode if cubicroot
    1611                 :          0 :             *pBody  = pNode->GetSubNode( 2 ); //Body of the root
    1612                 :            :     OSL_ENSURE( pBody, "pBody cannot be NULL" );
    1613                 :            : 
    1614                 :            :     SmCaretPosGraphEntry  *left,
    1615                 :            :                         *right,
    1616                 :            :                         *bodyLeft,
    1617                 :            :                         *bodyRight;
    1618                 :            : 
    1619                 :            :     //Get left and save it
    1620                 :            :     OSL_ENSURE( pRightMost, "There must be a position in front of this" );
    1621                 :          0 :     left = pRightMost;
    1622                 :            : 
    1623                 :            :     //Create body left
    1624         [ #  # ]:          0 :     bodyLeft = pGraph->Add( SmCaretPos( pBody, 0 ), left );
    1625                 :          0 :     left->SetRight( bodyLeft );
    1626                 :            : 
    1627                 :            :     //Create right
    1628         [ #  # ]:          0 :     right = pGraph->Add( SmCaretPos( pNode, 1 ) );
    1629                 :            : 
    1630                 :            :     //Visit body
    1631                 :          0 :     pRightMost = bodyLeft;
    1632                 :          0 :     pBody->Accept( this );
    1633                 :          0 :     bodyRight = pRightMost;
    1634                 :          0 :     bodyRight->SetRight( right );
    1635                 :          0 :     right->SetLeft( bodyRight );
    1636                 :            : 
    1637                 :            :     //Visit pExtra
    1638         [ #  # ]:          0 :     if( pExtra ){
    1639         [ #  # ]:          0 :         pRightMost = pGraph->Add( SmCaretPos( pExtra, 0 ), left );
    1640                 :          0 :         pExtra->Accept( this );
    1641                 :          0 :         pRightMost->SetRight( bodyLeft );
    1642                 :            :     }
    1643                 :            : 
    1644                 :          0 :     pRightMost = right;
    1645                 :          0 : }
    1646                 :            : 
    1647                 :            : /** Build SmCaretPosGraph for SmPlaceNode
    1648                 :            :  * Consider this a single character.
    1649                 :            :  */
    1650                 :          0 : void SmCaretPosGraphBuildingVisitor::Visit( SmPlaceNode* pNode )
    1651                 :            : {
    1652         [ #  # ]:          0 :     SmCaretPosGraphEntry* right = pGraph->Add( SmCaretPos( pNode, 1 ), pRightMost );
    1653                 :          0 :     pRightMost->SetRight( right );
    1654                 :          0 :     pRightMost = right;
    1655                 :          0 : }
    1656                 :            : 
    1657                 :            : /** SmErrorNode is context dependent metadata, it can't be selected
    1658                 :            :  *
    1659                 :            :  * @remarks There's no point in deleting, copying and/or moving an instance
    1660                 :            :  * of SmErrorNode as it may not exist in an other context! Thus there are no
    1661                 :            :  * positions to select an SmErrorNode.
    1662                 :            :  */
    1663                 :          0 : void SmCaretPosGraphBuildingVisitor::Visit( SmErrorNode* )
    1664                 :            : {
    1665                 :          0 : }
    1666                 :            : 
    1667                 :            : /** Build SmCaretPosGraph for SmBlankNode
    1668                 :            :  * Consider this a single character, as it is only a blank space
    1669                 :            :  */
    1670                 :          0 : void SmCaretPosGraphBuildingVisitor::Visit( SmBlankNode* pNode )
    1671                 :            : {
    1672         [ #  # ]:          0 :     SmCaretPosGraphEntry* right = pGraph->Add( SmCaretPos( pNode, 1 ), pRightMost );
    1673                 :          0 :     pRightMost->SetRight( right );
    1674                 :          0 :     pRightMost = right;
    1675                 :          0 : }
    1676                 :            : 
    1677                 :            : /** Build SmCaretPosGraph for SmBraceNode
    1678                 :            :  *
    1679                 :            :  * Lines in an SmBraceNode:
    1680                 :            :  * \code
    1681                 :            :  * |     |
    1682                 :            :  * |  B  |
    1683                 :            :  * |     |
    1684                 :            :  * \endcode
    1685                 :            :  * B: Body
    1686                 :            :  *
    1687                 :            :  * Graph over these, where "left" is before the SmBraceNode and "right" is after:
    1688                 :            :  * \dot
    1689                 :            :  *  digraph Graph{
    1690                 :            :  *      left -> B;
    1691                 :            :  *      B -> right;
    1692                 :            :  *  }
    1693                 :            :  * \enddot
    1694                 :            :  */
    1695                 :          0 : void SmCaretPosGraphBuildingVisitor::Visit( SmBraceNode* pNode )
    1696                 :            : {
    1697                 :          0 :     SmNode* pBody = pNode->GetSubNode( 1 );
    1698                 :            : 
    1699                 :          0 :     SmCaretPosGraphEntry  *left = pRightMost,
    1700         [ #  # ]:          0 :                         *right = pGraph->Add( SmCaretPos( pNode, 1 ) );
    1701                 :            : 
    1702         [ #  # ]:          0 :     if( pBody->GetType() != NBRACEBODY ) {
    1703         [ #  # ]:          0 :         pRightMost = pGraph->Add( SmCaretPos( pBody, 0 ), left );
    1704                 :          0 :         left->SetRight( pRightMost );
    1705                 :            :     }else
    1706                 :          0 :         pRightMost = left;
    1707                 :            : 
    1708                 :          0 :     pBody->Accept( this );
    1709                 :          0 :     pRightMost->SetRight( right );
    1710                 :          0 :     right->SetLeft( pRightMost );
    1711                 :            : 
    1712                 :          0 :     pRightMost = right;
    1713                 :          0 : }
    1714                 :            : 
    1715                 :            : /** Build SmCaretPosGraph for SmAttributNode
    1716                 :            :  *
    1717                 :            :  * Lines in an SmAttributNode:
    1718                 :            :  * \code
    1719                 :            :  *   Attr
    1720                 :            :  *   Body
    1721                 :            :  * \endcode
    1722                 :            :  *
    1723                 :            :  * There's a body and an attribute, the construction is used for "widehat A", where "A" is the body
    1724                 :            :  * and "^" is the attribute ( note GetScaleMode( ) on SmAttributNode tells how the attribute should be
    1725                 :            :  * scaled ).
    1726                 :            :  */
    1727                 :          0 : void SmCaretPosGraphBuildingVisitor::Visit( SmAttributNode* pNode )
    1728                 :            : {
    1729                 :          0 :     SmNode  *pAttr = pNode->GetSubNode( 0 ),
    1730                 :          0 :             *pBody = pNode->GetSubNode( 1 );
    1731                 :            :     //None of the children can be NULL
    1732                 :            : 
    1733                 :          0 :     SmCaretPosGraphEntry  *left = pRightMost,
    1734                 :            :                         *attrLeft,
    1735                 :            :                         *bodyLeft,
    1736                 :            :                         *bodyRight,
    1737                 :            :                         *right;
    1738                 :            : 
    1739                 :            :     //Creating bodyleft
    1740         [ #  # ]:          0 :     bodyLeft = pGraph->Add( SmCaretPos( pBody, 0 ), left );
    1741                 :          0 :     left->SetRight( bodyLeft );
    1742                 :            : 
    1743                 :            :     //Creating right
    1744         [ #  # ]:          0 :     right = pGraph->Add( SmCaretPos( pNode, 1 ) );
    1745                 :            : 
    1746                 :            :     //Visit the body
    1747                 :          0 :     pRightMost = bodyLeft;
    1748                 :          0 :     pBody->Accept( this );
    1749                 :          0 :     bodyRight = pRightMost;
    1750                 :          0 :     bodyRight->SetRight( right );
    1751                 :          0 :     right->SetLeft( bodyRight );
    1752                 :            : 
    1753                 :            :     //Create attrLeft
    1754         [ #  # ]:          0 :     attrLeft = pGraph->Add( SmCaretPos( pAttr, 0 ), left );
    1755                 :            : 
    1756                 :            :     //Visit attribute
    1757                 :          0 :     pRightMost = attrLeft;
    1758                 :          0 :     pAttr->Accept( this );
    1759                 :          0 :     pRightMost->SetRight( right );
    1760                 :            : 
    1761                 :            :     //Set return value
    1762                 :          0 :     pRightMost = right;
    1763                 :          0 : }
    1764                 :            : 
    1765                 :            : //Consider these single symboles
    1766                 :          0 : void SmCaretPosGraphBuildingVisitor::Visit( SmSpecialNode* pNode )
    1767                 :            : {
    1768         [ #  # ]:          0 :     SmCaretPosGraphEntry* right = pGraph->Add( SmCaretPos( pNode, 1 ), pRightMost );
    1769                 :          0 :     pRightMost->SetRight( right );
    1770                 :          0 :     pRightMost = right;
    1771                 :          0 : }
    1772                 :          0 : void SmCaretPosGraphBuildingVisitor::Visit( SmGlyphSpecialNode* pNode )
    1773                 :            : {
    1774         [ #  # ]:          0 :     SmCaretPosGraphEntry* right = pGraph->Add( SmCaretPos( pNode, 1 ), pRightMost );
    1775                 :          0 :     pRightMost->SetRight( right );
    1776                 :          0 :     pRightMost = right;
    1777                 :          0 : }
    1778                 :          0 : void SmCaretPosGraphBuildingVisitor::Visit( SmMathSymbolNode* pNode )
    1779                 :            : {
    1780         [ #  # ]:          0 :     SmCaretPosGraphEntry* right = pGraph->Add( SmCaretPos( pNode, 1 ), pRightMost );
    1781                 :          0 :     pRightMost->SetRight( right );
    1782                 :          0 :     pRightMost = right;
    1783                 :          0 : }
    1784                 :            : 
    1785                 :          0 : void SmCaretPosGraphBuildingVisitor::Visit( SmRootSymbolNode* )
    1786                 :            : {
    1787                 :            :     //Do nothing
    1788                 :          0 : }
    1789                 :          0 : void SmCaretPosGraphBuildingVisitor::Visit( SmRectangleNode* )
    1790                 :            : {
    1791                 :            :     //Do nothing
    1792                 :          0 : }
    1793                 :          0 : void SmCaretPosGraphBuildingVisitor::Visit( SmPolyLineNode* )
    1794                 :            : {
    1795                 :            :     //Do nothing
    1796                 :          0 : }
    1797                 :            : 
    1798                 :            : /////////////////////////////// SmCloningVisitor ///////////////////////////////
    1799                 :            : 
    1800                 :          0 : SmNode* SmCloningVisitor::Clone( SmNode* pNode )
    1801                 :            : {
    1802                 :          0 :     SmNode* pCurrResult = pResult;
    1803                 :          0 :     pNode->Accept( this );
    1804                 :          0 :     SmNode* pClone = pResult;
    1805                 :          0 :     pResult = pCurrResult;
    1806                 :          0 :     return pClone;
    1807                 :            : }
    1808                 :            : 
    1809                 :          0 : void SmCloningVisitor::CloneNodeAttr( SmNode* pSource, SmNode* pTarget )
    1810                 :            : {
    1811                 :          0 :     pTarget->SetScaleMode( pSource->GetScaleMode( ) );
    1812                 :            :     //Other attributes are set when prepare or arrange is executed
    1813                 :            :     //and may depend on stuff not being cloned here.
    1814                 :          0 : }
    1815                 :            : 
    1816                 :          0 : void SmCloningVisitor::CloneKids( SmStructureNode* pSource, SmStructureNode* pTarget )
    1817                 :            : {
    1818                 :            :     //Cache current result
    1819                 :          0 :     SmNode* pCurrResult = pResult;
    1820                 :            : 
    1821                 :            :     //Create array for holding clones
    1822         [ #  # ]:          0 :     sal_uInt16 nSize = pSource->GetNumSubNodes( );
    1823         [ #  # ]:          0 :     SmNodeArray aNodes( nSize );
    1824                 :            : 
    1825                 :            :     //Clone children
    1826                 :            :     SmNode* pKid;
    1827         [ #  # ]:          0 :     for( sal_uInt16 i = 0; i < nSize; i++ ){
    1828 [ #  # ][ #  # ]:          0 :         if( NULL != ( pKid = pSource->GetSubNode( i ) ) )
    1829         [ #  # ]:          0 :             pKid->Accept( this );
    1830                 :            :         else
    1831                 :          0 :             pResult = NULL;
    1832                 :          0 :         aNodes[i] = pResult;
    1833                 :            :     }
    1834                 :            : 
    1835                 :            :     //Set subnodes of pTarget
    1836         [ #  # ]:          0 :     pTarget->SetSubNodes( aNodes );
    1837                 :            : 
    1838                 :            :     //Restore result as where prior to call
    1839                 :          0 :     pResult = pCurrResult;
    1840                 :          0 : }
    1841                 :            : 
    1842                 :          0 : void SmCloningVisitor::Visit( SmTableNode* pNode )
    1843                 :            : {
    1844         [ #  # ]:          0 :     SmTableNode* pClone = new SmTableNode( pNode->GetToken( ) );
    1845                 :          0 :     CloneNodeAttr( pNode, pClone );
    1846                 :          0 :     CloneKids( pNode, pClone );
    1847                 :          0 :     pResult = pClone;
    1848                 :          0 : }
    1849                 :            : 
    1850                 :          0 : void SmCloningVisitor::Visit( SmBraceNode* pNode )
    1851                 :            : {
    1852         [ #  # ]:          0 :     SmBraceNode* pClone = new SmBraceNode( pNode->GetToken( ) );
    1853                 :          0 :     CloneNodeAttr( pNode, pClone );
    1854                 :          0 :     CloneKids( pNode, pClone );
    1855                 :          0 :     pResult = pClone;
    1856                 :          0 : }
    1857                 :            : 
    1858                 :          0 : void SmCloningVisitor::Visit( SmBracebodyNode* pNode )
    1859                 :            : {
    1860         [ #  # ]:          0 :     SmBracebodyNode* pClone = new SmBracebodyNode( pNode->GetToken( ) );
    1861                 :          0 :     CloneNodeAttr( pNode, pClone );
    1862                 :          0 :     CloneKids( pNode, pClone );
    1863                 :          0 :     pResult = pClone;
    1864                 :          0 : }
    1865                 :            : 
    1866                 :          0 : void SmCloningVisitor::Visit( SmOperNode* pNode )
    1867                 :            : {
    1868         [ #  # ]:          0 :     SmOperNode* pClone = new SmOperNode( pNode->GetToken( ) );
    1869                 :          0 :     CloneNodeAttr( pNode, pClone );
    1870                 :          0 :     CloneKids( pNode, pClone );
    1871                 :          0 :     pResult = pClone;
    1872                 :          0 : }
    1873                 :            : 
    1874                 :          0 : void SmCloningVisitor::Visit( SmAlignNode* pNode )
    1875                 :            : {
    1876         [ #  # ]:          0 :     SmAlignNode* pClone = new SmAlignNode( pNode->GetToken( ) );
    1877                 :          0 :     CloneNodeAttr( pNode, pClone );
    1878                 :          0 :     CloneKids( pNode, pClone );
    1879                 :          0 :     pResult = pClone;
    1880                 :          0 : }
    1881                 :            : 
    1882                 :          0 : void SmCloningVisitor::Visit( SmAttributNode* pNode )
    1883                 :            : {
    1884         [ #  # ]:          0 :     SmAttributNode* pClone = new SmAttributNode( pNode->GetToken( ) );
    1885                 :          0 :     CloneNodeAttr( pNode, pClone );
    1886                 :          0 :     CloneKids( pNode, pClone );
    1887                 :          0 :     pResult = pClone;
    1888                 :          0 : }
    1889                 :            : 
    1890                 :          0 : void SmCloningVisitor::Visit( SmFontNode* pNode )
    1891                 :            : {
    1892         [ #  # ]:          0 :     SmFontNode* pClone = new SmFontNode( pNode->GetToken( ) );
    1893                 :          0 :     pClone->SetSizeParameter( pNode->GetSizeParameter( ), pNode->GetSizeType( ) );
    1894                 :          0 :     CloneNodeAttr( pNode, pClone );
    1895                 :          0 :     CloneKids( pNode, pClone );
    1896                 :          0 :     pResult = pClone;
    1897                 :          0 : }
    1898                 :            : 
    1899                 :          0 : void SmCloningVisitor::Visit( SmUnHorNode* pNode )
    1900                 :            : {
    1901         [ #  # ]:          0 :     SmUnHorNode* pClone = new SmUnHorNode( pNode->GetToken( ) );
    1902                 :          0 :     CloneNodeAttr( pNode, pClone );
    1903                 :          0 :     CloneKids( pNode, pClone );
    1904                 :          0 :     pResult = pClone;
    1905                 :          0 : }
    1906                 :            : 
    1907                 :          0 : void SmCloningVisitor::Visit( SmBinHorNode* pNode )
    1908                 :            : {
    1909         [ #  # ]:          0 :     SmBinHorNode* pClone = new SmBinHorNode( pNode->GetToken( ) );
    1910                 :          0 :     CloneNodeAttr( pNode, pClone );
    1911                 :          0 :     CloneKids( pNode, pClone );
    1912                 :          0 :     pResult = pClone;
    1913                 :          0 : }
    1914                 :            : 
    1915                 :          0 : void SmCloningVisitor::Visit( SmBinVerNode* pNode )
    1916                 :            : {
    1917         [ #  # ]:          0 :     SmBinVerNode* pClone = new SmBinVerNode( pNode->GetToken( ) );
    1918                 :          0 :     CloneNodeAttr( pNode, pClone );
    1919                 :          0 :     CloneKids( pNode, pClone );
    1920                 :          0 :     pResult = pClone;
    1921                 :          0 : }
    1922                 :            : 
    1923                 :          0 : void SmCloningVisitor::Visit( SmBinDiagonalNode* pNode )
    1924                 :            : {
    1925         [ #  # ]:          0 :     SmBinDiagonalNode *pClone = new SmBinDiagonalNode( pNode->GetToken( ) );
    1926                 :          0 :     pClone->SetAscending( pNode->IsAscending( ) );
    1927                 :          0 :     CloneNodeAttr( pNode, pClone );
    1928                 :          0 :     CloneKids( pNode, pClone );
    1929                 :          0 :     pResult = pClone;
    1930                 :          0 : }
    1931                 :            : 
    1932                 :          0 : void SmCloningVisitor::Visit( SmSubSupNode* pNode )
    1933                 :            : {
    1934         [ #  # ]:          0 :     SmSubSupNode *pClone = new SmSubSupNode( pNode->GetToken( ) );
    1935                 :          0 :     pClone->SetUseLimits( pNode->IsUseLimits( ) );
    1936                 :          0 :     CloneNodeAttr( pNode, pClone );
    1937                 :          0 :     CloneKids( pNode, pClone );
    1938                 :          0 :     pResult = pClone;
    1939                 :          0 : }
    1940                 :            : 
    1941                 :          0 : void SmCloningVisitor::Visit( SmMatrixNode* pNode )
    1942                 :            : {
    1943         [ #  # ]:          0 :     SmMatrixNode *pClone = new SmMatrixNode( pNode->GetToken( ) );
    1944                 :          0 :     pClone->SetRowCol( pNode->GetNumRows( ), pNode->GetNumCols( ) );
    1945                 :          0 :     CloneNodeAttr( pNode, pClone );
    1946                 :          0 :     CloneKids( pNode, pClone );
    1947                 :          0 :     pResult = pClone;
    1948                 :          0 : }
    1949                 :            : 
    1950                 :          0 : void SmCloningVisitor::Visit( SmPlaceNode* pNode )
    1951                 :            : {
    1952         [ #  # ]:          0 :     pResult = new SmPlaceNode( pNode->GetToken( ) );
    1953                 :          0 :     CloneNodeAttr( pNode, pResult );
    1954                 :          0 : }
    1955                 :            : 
    1956                 :          0 : void SmCloningVisitor::Visit( SmTextNode* pNode )
    1957                 :            : {
    1958         [ #  # ]:          0 :     SmTextNode* pClone = new SmTextNode( pNode->GetToken( ), pNode->GetFontDesc( ) );
    1959                 :          0 :     pClone->ChangeText( pNode->GetText( ) );
    1960                 :          0 :     CloneNodeAttr( pNode, pClone );
    1961                 :          0 :     pResult = pClone;
    1962                 :          0 : }
    1963                 :            : 
    1964                 :          0 : void SmCloningVisitor::Visit( SmSpecialNode* pNode )
    1965                 :            : {
    1966         [ #  # ]:          0 :     pResult = new SmSpecialNode( pNode->GetToken( ) );
    1967                 :          0 :     CloneNodeAttr( pNode, pResult );
    1968                 :          0 : }
    1969                 :            : 
    1970                 :          0 : void SmCloningVisitor::Visit( SmGlyphSpecialNode* pNode )
    1971                 :            : {
    1972         [ #  # ]:          0 :     pResult = new SmGlyphSpecialNode( pNode->GetToken( ) );
    1973                 :          0 :     CloneNodeAttr( pNode, pResult );
    1974                 :          0 : }
    1975                 :            : 
    1976                 :          0 : void SmCloningVisitor::Visit( SmMathSymbolNode* pNode )
    1977                 :            : {
    1978         [ #  # ]:          0 :     pResult = new SmMathSymbolNode( pNode->GetToken( ) );
    1979                 :          0 :     CloneNodeAttr( pNode, pResult );
    1980                 :          0 : }
    1981                 :            : 
    1982                 :          0 : void SmCloningVisitor::Visit( SmBlankNode* pNode )
    1983                 :            : {
    1984         [ #  # ]:          0 :     SmBlankNode* pClone = new SmBlankNode( pNode->GetToken( ) );
    1985                 :          0 :     pClone->SetBlankNum( pNode->GetBlankNum( ) );
    1986                 :          0 :     pResult = pClone;
    1987                 :          0 :     CloneNodeAttr( pNode, pResult );
    1988                 :          0 : }
    1989                 :            : 
    1990                 :          0 : void SmCloningVisitor::Visit( SmErrorNode* pNode )
    1991                 :            : {
    1992                 :            :     //PE_NONE is used the information have been discarded and isn't used
    1993         [ #  # ]:          0 :     pResult = new SmErrorNode( PE_NONE, pNode->GetToken( ) );
    1994                 :          0 :     CloneNodeAttr( pNode, pResult );
    1995                 :          0 : }
    1996                 :            : 
    1997                 :          0 : void SmCloningVisitor::Visit( SmLineNode* pNode )
    1998                 :            : {
    1999         [ #  # ]:          0 :     SmLineNode* pClone = new SmLineNode( pNode->GetToken( ) );
    2000                 :          0 :     CloneNodeAttr( pNode, pClone );
    2001                 :          0 :     CloneKids( pNode, pClone );
    2002                 :          0 :     pResult = pClone;
    2003                 :          0 : }
    2004                 :            : 
    2005                 :          0 : void SmCloningVisitor::Visit( SmExpressionNode* pNode )
    2006                 :            : {
    2007         [ #  # ]:          0 :     SmExpressionNode* pClone = new SmExpressionNode( pNode->GetToken( ) );
    2008                 :          0 :     CloneNodeAttr( pNode, pClone );
    2009                 :          0 :     CloneKids( pNode, pClone );
    2010                 :          0 :     pResult = pClone;
    2011                 :          0 : }
    2012                 :            : 
    2013                 :          0 : void SmCloningVisitor::Visit( SmPolyLineNode* pNode )
    2014                 :            : {
    2015         [ #  # ]:          0 :     pResult = new SmPolyLineNode( pNode->GetToken( ) );
    2016                 :          0 :     CloneNodeAttr( pNode, pResult );
    2017                 :          0 : }
    2018                 :            : 
    2019                 :          0 : void SmCloningVisitor::Visit( SmRootNode* pNode )
    2020                 :            : {
    2021         [ #  # ]:          0 :     SmRootNode* pClone = new SmRootNode( pNode->GetToken( ) );
    2022                 :          0 :     CloneNodeAttr( pNode, pClone );
    2023                 :          0 :     CloneKids( pNode, pClone );
    2024                 :          0 :     pResult = pClone;
    2025                 :          0 : }
    2026                 :            : 
    2027                 :          0 : void SmCloningVisitor::Visit( SmRootSymbolNode* pNode )
    2028                 :            : {
    2029         [ #  # ]:          0 :     pResult = new SmRootSymbolNode( pNode->GetToken( ) );
    2030                 :          0 :     CloneNodeAttr( pNode, pResult );
    2031                 :          0 : }
    2032                 :            : 
    2033                 :          0 : void SmCloningVisitor::Visit( SmRectangleNode* pNode )
    2034                 :            : {
    2035         [ #  # ]:          0 :     pResult = new SmRectangleNode( pNode->GetToken( ) );
    2036                 :          0 :     CloneNodeAttr( pNode, pResult );
    2037                 :          0 : }
    2038                 :            : 
    2039                 :          0 : void SmCloningVisitor::Visit( SmVerticalBraceNode* pNode )
    2040                 :            : {
    2041         [ #  # ]:          0 :     SmVerticalBraceNode* pClone = new SmVerticalBraceNode( pNode->GetToken( ) );
    2042                 :          0 :     CloneNodeAttr( pNode, pClone );
    2043                 :          0 :     CloneKids( pNode, pClone );
    2044                 :          0 :     pResult = pClone;
    2045                 :          0 : }
    2046                 :            : 
    2047                 :            : /////////////////////////////// SmSelectionDrawingVisitor ///////////////////////////////
    2048                 :            : 
    2049                 :          0 : SmSelectionDrawingVisitor::SmSelectionDrawingVisitor( OutputDevice& rDevice, SmNode* pTree, Point Offset )
    2050         [ #  # ]:          0 :     : rDev( rDevice ) {
    2051                 :          0 :     bHasSelectionArea = false;
    2052                 :            : 
    2053                 :            :     //Visit everything
    2054                 :            :     OSL_ENSURE( pTree, "pTree can't be null!" );
    2055         [ #  # ]:          0 :     if( pTree )
    2056         [ #  # ]:          0 :         pTree->Accept( this );
    2057                 :            : 
    2058                 :            :     //Draw selection if there's any
    2059         [ #  # ]:          0 :     if( bHasSelectionArea ){
    2060         [ #  # ]:          0 :         aSelectionArea.Move( Offset.X( ), Offset.Y( ) );
    2061                 :            : 
    2062                 :            :         //Save device state
    2063         [ #  # ]:          0 :         rDev.Push( PUSH_LINECOLOR | PUSH_FILLCOLOR );
    2064                 :            :         //Change colors
    2065         [ #  # ]:          0 :         rDev.SetLineColor( );
    2066         [ #  # ]:          0 :         rDev.SetFillColor( Color( COL_LIGHTGRAY ) );
    2067                 :            : 
    2068                 :            :         //Draw rectangle
    2069         [ #  # ]:          0 :         rDev.DrawRect( aSelectionArea );
    2070                 :            : 
    2071                 :            :         //Restore device state
    2072         [ #  # ]:          0 :         rDev.Pop( );
    2073                 :            :     }
    2074                 :          0 : }
    2075                 :            : 
    2076                 :          0 : void SmSelectionDrawingVisitor::ExtendSelectionArea( Rectangle aArea )
    2077                 :            : {
    2078         [ #  # ]:          0 :     if ( ! bHasSelectionArea ) {
    2079                 :          0 :         aSelectionArea = aArea;
    2080                 :          0 :         bHasSelectionArea = true;
    2081                 :            :     } else
    2082                 :          0 :         aSelectionArea.Union( aArea );
    2083                 :          0 : }
    2084                 :            : 
    2085                 :          0 : void SmSelectionDrawingVisitor::DefaultVisit( SmNode* pNode )
    2086                 :            : {
    2087         [ #  # ]:          0 :     if( pNode->IsSelected( ) )
    2088                 :          0 :         ExtendSelectionArea( pNode->AsRectangle( ) );
    2089                 :          0 :     VisitChildren( pNode );
    2090                 :          0 : }
    2091                 :            : 
    2092                 :          0 : void SmSelectionDrawingVisitor::VisitChildren( SmNode* pNode )
    2093                 :            : {
    2094         [ #  # ]:          0 :     SmNodeIterator it( pNode );
    2095 [ #  # ][ #  # ]:          0 :     while( it.Next( ) )
    2096         [ #  # ]:          0 :         it->Accept( this );
    2097                 :          0 : }
    2098                 :            : 
    2099                 :          0 : void SmSelectionDrawingVisitor::Visit( SmTextNode* pNode )
    2100                 :            : {
    2101         [ #  # ]:          0 :     if( pNode->IsSelected( ) ){
    2102         [ #  # ]:          0 :         rDev.Push( PUSH_TEXTCOLOR | PUSH_FONT );
    2103                 :            : 
    2104         [ #  # ]:          0 :         rDev.SetFont( pNode->GetFont( ) );
    2105                 :          0 :         Point Position = pNode->GetTopLeft( );
    2106         [ #  # ]:          0 :         long left   = Position.getX( ) + rDev.GetTextWidth( pNode->GetText( ), 0, pNode->GetSelectionStart( ) );
    2107         [ #  # ]:          0 :         long right  = Position.getX( ) + rDev.GetTextWidth( pNode->GetText( ), 0, pNode->GetSelectionEnd( ) );
    2108                 :          0 :         long top    = Position.getY( );
    2109         [ #  # ]:          0 :         long bottom = top + pNode->GetHeight( );
    2110         [ #  # ]:          0 :         Rectangle rect( left, top, right, bottom );
    2111                 :            : 
    2112         [ #  # ]:          0 :         ExtendSelectionArea( rect );
    2113                 :            : 
    2114         [ #  # ]:          0 :         rDev.Pop( );
    2115                 :            :     }
    2116                 :          0 : }
    2117                 :            : 
    2118                 :            : /////////////////////////////// SmNodeToTextVisitor ///////////////////////////////
    2119                 :            : 
    2120                 :          0 : void SmNodeToTextVisitor::Visit( SmTableNode* pNode )
    2121                 :            : {
    2122         [ #  # ]:          0 :     if( pNode->GetToken( ).eType == TBINOM ) {
    2123                 :          0 :         Append( "{ binom" );
    2124                 :          0 :         LineToText( pNode->GetSubNode( 0 ) );
    2125                 :          0 :         LineToText( pNode->GetSubNode( 1 ) );
    2126                 :          0 :         Append("} ");
    2127         [ #  # ]:          0 :     } else if( pNode->GetToken( ).eType == TSTACK ) {
    2128         [ #  # ]:          0 :         Append( "stack{ " );
    2129         [ #  # ]:          0 :         SmNodeIterator it( pNode );
    2130         [ #  # ]:          0 :         it.Next( );
    2131                 :          0 :         while( true ) {
    2132         [ #  # ]:          0 :             LineToText( it.Current( ) );
    2133 [ #  # ][ #  # ]:          0 :             if( it.Next( ) ) {
    2134         [ #  # ]:          0 :                 Separate( );
    2135         [ #  # ]:          0 :                 Append( "# " );
    2136                 :            :             }else
    2137                 :          0 :                 break;
    2138                 :            :         }
    2139         [ #  # ]:          0 :         Separate( );
    2140         [ #  # ]:          0 :         Append( "}" );
    2141                 :            :     } else { //Assume it's a toplevel table, containing lines
    2142         [ #  # ]:          0 :         SmNodeIterator it( pNode );
    2143         [ #  # ]:          0 :         it.Next( );
    2144                 :          0 :         while( true ) {
    2145         [ #  # ]:          0 :             Separate( );
    2146         [ #  # ]:          0 :             it->Accept( this );
    2147 [ #  # ][ #  # ]:          0 :             if( it.Next( ) ) {
    2148         [ #  # ]:          0 :                 Separate( );
    2149         [ #  # ]:          0 :                 Append( "newline" );
    2150                 :            :             }else
    2151                 :          0 :                 break;
    2152                 :            :         }
    2153                 :            :     }
    2154                 :          0 : }
    2155                 :            : 
    2156                 :          0 : void SmNodeToTextVisitor::Visit( SmBraceNode* pNode )
    2157                 :            : {
    2158                 :          0 :     SmNode *pLeftBrace  = pNode->GetSubNode( 0 ),
    2159                 :          0 :            *pBody       = pNode->GetSubNode( 1 ),
    2160                 :          0 :            *pRightBrace = pNode->GetSubNode( 2 );
    2161                 :            :     //Handle special case where it's absolute function
    2162         [ #  # ]:          0 :     if( pNode->GetToken( ).eType == TABS ) {
    2163                 :          0 :         Append( "abs" );
    2164                 :          0 :         LineToText( pBody );
    2165                 :            :     } else {
    2166         [ #  # ]:          0 :         if( pNode->GetScaleMode( ) == SCALE_HEIGHT )
    2167                 :          0 :             Append( "left " );
    2168                 :          0 :         pLeftBrace->Accept( this );
    2169                 :          0 :         Separate( );
    2170                 :          0 :         pBody->Accept( this );
    2171                 :          0 :         Separate( );
    2172         [ #  # ]:          0 :         if( pNode->GetScaleMode( ) == SCALE_HEIGHT )
    2173                 :          0 :             Append( "right " );
    2174                 :          0 :         pRightBrace->Accept( this );
    2175                 :            :     }
    2176                 :          0 : }
    2177                 :            : 
    2178                 :          0 : void SmNodeToTextVisitor::Visit( SmBracebodyNode* pNode )
    2179                 :            : {
    2180         [ #  # ]:          0 :     SmNodeIterator it( pNode );
    2181 [ #  # ][ #  # ]:          0 :     while( it.Next( ) ){
    2182         [ #  # ]:          0 :         Separate( );
    2183         [ #  # ]:          0 :         it->Accept( this );
    2184                 :            :     }
    2185                 :          0 : }
    2186                 :            : 
    2187                 :          0 : void SmNodeToTextVisitor::Visit( SmOperNode* pNode )
    2188                 :            : {
    2189                 :          0 :     Append( pNode->GetToken( ).aText );
    2190                 :          0 :     Separate( );
    2191         [ #  # ]:          0 :     if( pNode->GetToken( ).eType == TOPER ){
    2192                 :            :         //There's an SmGlyphSpecialNode if eType == TOPER
    2193         [ #  # ]:          0 :         if( pNode->GetSubNode( 0 )->GetType( ) == NSUBSUP )
    2194                 :          0 :             Append( pNode->GetSubNode( 0 )->GetSubNode( 0 )->GetToken( ).aText );
    2195                 :            :         else
    2196                 :          0 :             Append( pNode->GetSubNode( 0 )->GetToken( ).aText );
    2197                 :            :     }
    2198         [ #  # ]:          0 :     if( pNode->GetSubNode( 0 )->GetType( ) == NSUBSUP ) {
    2199                 :          0 :         SmSubSupNode *pSubSup = ( SmSubSupNode* )pNode->GetSubNode( 0 );
    2200                 :            :         SmNode* pChild;
    2201         [ #  # ]:          0 :         if( ( pChild = pSubSup->GetSubSup( LSUP ) ) ) {
    2202                 :          0 :             Separate( );
    2203                 :          0 :             Append( "lsup { " );
    2204                 :          0 :             LineToText( pChild );
    2205                 :          0 :             Append( "} " );
    2206                 :            :         }
    2207         [ #  # ]:          0 :         if( ( pChild = pSubSup->GetSubSup( LSUB ) ) ) {
    2208                 :          0 :             Separate( );
    2209                 :          0 :             Append( "lsub { " );
    2210                 :          0 :             LineToText( pChild );
    2211                 :          0 :             Append( "} " );
    2212                 :            :         }
    2213         [ #  # ]:          0 :         if( ( pChild = pSubSup->GetSubSup( RSUP ) ) ) {
    2214                 :          0 :             Separate( );
    2215                 :          0 :             Append( "^ { " );
    2216                 :          0 :             LineToText( pChild );
    2217                 :          0 :             Append( "} " );
    2218                 :            :         }
    2219         [ #  # ]:          0 :         if( ( pChild = pSubSup->GetSubSup( RSUB ) ) ) {
    2220                 :          0 :             Separate( );
    2221                 :          0 :             Append( "_ { " );
    2222                 :          0 :             LineToText( pChild );
    2223                 :          0 :             Append( "} " );
    2224                 :            :         }
    2225         [ #  # ]:          0 :         if( ( pChild = pSubSup->GetSubSup( CSUB ) ) ) {
    2226                 :          0 :             Separate( );
    2227         [ #  # ]:          0 :             if (pSubSup->IsUseLimits())
    2228                 :          0 :                 Append( "from { " );
    2229                 :            :             else
    2230                 :          0 :                 Append( "csub { " );
    2231                 :          0 :             LineToText( pChild );
    2232                 :          0 :             Append( "} " );
    2233                 :            :         }
    2234         [ #  # ]:          0 :         if( ( pChild = pSubSup->GetSubSup( CSUP ) ) ) {
    2235                 :          0 :             Separate( );
    2236         [ #  # ]:          0 :             if (pSubSup->IsUseLimits())
    2237                 :          0 :                 Append( "to { " );
    2238                 :            :             else
    2239                 :          0 :                 Append( "csup { " );
    2240                 :          0 :             LineToText( pChild );
    2241                 :          0 :             Append( "} " );
    2242                 :            :         }
    2243                 :            :     }
    2244                 :          0 :     LineToText( pNode->GetSubNode( 1 ) );
    2245                 :          0 : }
    2246                 :            : 
    2247                 :          0 : void SmNodeToTextVisitor::Visit( SmAlignNode* pNode )
    2248                 :            : {
    2249                 :          0 :     Append( pNode->GetToken( ).aText );
    2250                 :          0 :     LineToText( pNode->GetSubNode( 0 ) );
    2251                 :          0 : }
    2252                 :            : 
    2253                 :          0 : void SmNodeToTextVisitor::Visit( SmAttributNode* pNode )
    2254                 :            : {
    2255                 :          0 :     Append( pNode->GetToken( ).aText );
    2256                 :          0 :     LineToText( pNode->GetSubNode( 1 ) );
    2257                 :          0 : }
    2258                 :            : 
    2259                 :          0 : void SmNodeToTextVisitor::Visit( SmFontNode* pNode )
    2260                 :            : {
    2261   [ #  #  #  #  :          0 :     switch ( pNode->GetToken( ).eType )
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
    2262                 :            :     {
    2263                 :            :         case TBOLD:
    2264                 :          0 :             Append( "bold " );
    2265                 :          0 :             break;
    2266                 :            :         case TNBOLD:
    2267                 :          0 :             Append( "nbold " );
    2268                 :          0 :             break;
    2269                 :            :         case TITALIC:
    2270                 :          0 :             Append( "italic " );
    2271                 :          0 :             break;
    2272                 :            :         case TNITALIC:
    2273                 :          0 :             Append( "nitalic " );
    2274                 :          0 :             break;
    2275                 :            :         case TPHANTOM:
    2276                 :          0 :             Append( "phantom " );
    2277                 :          0 :             break;
    2278                 :            :         case TSIZE:
    2279                 :            :             {
    2280                 :          0 :                 Append( "size " );
    2281   [ #  #  #  #  :          0 :                 switch ( pNode->GetSizeType( ) )
                      # ]
    2282                 :            :                 {
    2283                 :            :                     case FNTSIZ_PLUS:
    2284                 :          0 :                         Append( "+" );
    2285                 :          0 :                         break;
    2286                 :            :                     case FNTSIZ_MINUS:
    2287                 :          0 :                         Append( "-" );
    2288                 :          0 :                         break;
    2289                 :            :                     case FNTSIZ_MULTIPLY:
    2290                 :          0 :                         Append( "*" );
    2291                 :          0 :                         break;
    2292                 :            :                     case FNTSIZ_DIVIDE:
    2293                 :          0 :                         Append( "/" );
    2294                 :          0 :                         break;
    2295                 :            :                     case FNTSIZ_ABSOLUT:
    2296                 :            :                     default:
    2297                 :          0 :                         break;
    2298                 :            :                 }
    2299                 :            :                 Append( String( ::rtl::math::doubleToUString(
    2300                 :          0 :                             static_cast<double>( pNode->GetSizeParameter( ) ),
    2301                 :            :                             rtl_math_StringFormat_Automatic,
    2302 [ #  # ][ #  # ]:          0 :                             rtl_math_DecimalPlaces_Max, '.', sal_True ) ) );
                 [ #  # ]
    2303                 :          0 :                 Append( " " );
    2304                 :            :             }
    2305                 :          0 :             break;
    2306                 :            :         case TBLACK:
    2307                 :          0 :             Append( "color black " );
    2308                 :          0 :             break;
    2309                 :            :         case TWHITE:
    2310                 :          0 :             Append( "color white " );
    2311                 :          0 :             break;
    2312                 :            :         case TRED:
    2313                 :          0 :             Append( "color red " );
    2314                 :          0 :             break;
    2315                 :            :         case TGREEN:
    2316                 :          0 :             Append( "color green " );
    2317                 :          0 :             break;
    2318                 :            :         case TBLUE:
    2319                 :          0 :             Append( "color blue " );
    2320                 :          0 :             break;
    2321                 :            :         case TCYAN:
    2322                 :          0 :             Append( "color cyan " );
    2323                 :          0 :             break;
    2324                 :            :         case TMAGENTA:
    2325                 :          0 :             Append( "color magenta " );
    2326                 :          0 :             break;
    2327                 :            :         case TYELLOW:
    2328                 :          0 :             Append( "color yellow " );
    2329                 :          0 :             break;
    2330                 :            :         case TSANS:
    2331                 :          0 :             Append( "font sans " );
    2332                 :          0 :             break;
    2333                 :            :         case TSERIF:
    2334                 :          0 :             Append( "font serif " );
    2335                 :          0 :             break;
    2336                 :            :         case TFIXED:
    2337                 :          0 :             Append( "font fixed " );
    2338                 :          0 :             break;
    2339                 :            :         default:
    2340                 :          0 :             break;
    2341                 :            :     }
    2342                 :          0 :     LineToText( pNode->GetSubNode( 1 ) );
    2343                 :          0 : }
    2344                 :            : 
    2345                 :          0 : void SmNodeToTextVisitor::Visit( SmUnHorNode* pNode )
    2346                 :            : {
    2347 [ #  # ][ #  # ]:          0 :     SmNodeIterator it( pNode, pNode->GetSubNode( 1 )->GetToken( ).eType == TFACT );
    2348 [ #  # ][ #  # ]:          0 :     while( it.Next( ) ) {
    2349         [ #  # ]:          0 :         Separate( );
    2350         [ #  # ]:          0 :         it->Accept( this );
    2351                 :            :     }
    2352                 :          0 : }
    2353                 :            : 
    2354                 :          0 : void SmNodeToTextVisitor::Visit( SmBinHorNode* pNode )
    2355                 :            : {
    2356                 :          0 :     SmNode *pLeft  = pNode->GetSubNode( 0 ),
    2357                 :          0 :            *pOper  = pNode->GetSubNode( 1 ),
    2358                 :          0 :            *pRight = pNode->GetSubNode( 2 );
    2359                 :          0 :     Separate( );
    2360                 :          0 :     pLeft->Accept( this );
    2361                 :          0 :     Separate( );
    2362                 :          0 :     pOper->Accept( this );
    2363                 :          0 :     Separate( );
    2364                 :          0 :     pRight->Accept( this );
    2365                 :          0 :     Separate( );
    2366                 :          0 : }
    2367                 :            : 
    2368                 :          0 : void SmNodeToTextVisitor::Visit( SmBinVerNode* pNode )
    2369                 :            : {
    2370                 :          0 :     SmNode *pNum    = pNode->GetSubNode( 0 ),
    2371                 :          0 :            *pDenom  = pNode->GetSubNode( 2 );
    2372                 :          0 :     Append( "{ " );
    2373                 :          0 :     LineToText( pNum );
    2374                 :          0 :     Append( "over" );
    2375                 :          0 :     LineToText( pDenom );
    2376                 :          0 :     Append( "} " );
    2377                 :          0 : }
    2378                 :            : 
    2379                 :          0 : void SmNodeToTextVisitor::Visit( SmBinDiagonalNode* pNode )
    2380                 :            : {
    2381                 :          0 :     SmNode *pLeftOperand  = pNode->GetSubNode( 0 ),
    2382                 :          0 :            *pRightOperand = pNode->GetSubNode( 1 );
    2383                 :          0 :     Append( "{ " );
    2384                 :          0 :     LineToText( pLeftOperand );
    2385                 :          0 :     Separate( );
    2386                 :          0 :     Append( "wideslash " );
    2387                 :          0 :     LineToText( pRightOperand );
    2388                 :          0 :     Append( "} " );
    2389                 :          0 : }
    2390                 :            : 
    2391                 :          0 : void SmNodeToTextVisitor::Visit( SmSubSupNode* pNode )
    2392                 :            : {
    2393                 :          0 :     LineToText( pNode->GetBody( ) );
    2394                 :            :     SmNode *pChild;
    2395         [ #  # ]:          0 :     if( ( pChild = pNode->GetSubSup( LSUP ) ) ) {
    2396                 :          0 :         Separate( );
    2397                 :          0 :         Append( "lsup " );
    2398                 :          0 :         LineToText( pChild );
    2399                 :            :     }
    2400         [ #  # ]:          0 :     if( ( pChild = pNode->GetSubSup( LSUB ) ) ) {
    2401                 :          0 :         Separate( );
    2402                 :          0 :         Append( "lsub " );
    2403                 :          0 :         LineToText( pChild );
    2404                 :            :     }
    2405         [ #  # ]:          0 :     if( ( pChild = pNode->GetSubSup( RSUP ) ) ) {
    2406                 :          0 :         Separate( );
    2407                 :          0 :         Append( "^ " );
    2408                 :          0 :         LineToText( pChild );
    2409                 :            :     }
    2410         [ #  # ]:          0 :     if( ( pChild = pNode->GetSubSup( RSUB ) ) ) {
    2411                 :          0 :         Separate( );
    2412                 :          0 :         Append( "_ " );
    2413                 :          0 :         LineToText( pChild );
    2414                 :            :     }
    2415         [ #  # ]:          0 :     if( ( pChild = pNode->GetSubSup( CSUB ) ) ) {
    2416                 :          0 :         Separate( );
    2417         [ #  # ]:          0 :         if (pNode->IsUseLimits())
    2418                 :          0 :             Append( "from " );
    2419                 :            :         else
    2420                 :          0 :             Append( "csub " );
    2421                 :          0 :         LineToText( pChild );
    2422                 :            :     }
    2423         [ #  # ]:          0 :     if( ( pChild = pNode->GetSubSup( CSUP ) ) ) {
    2424                 :          0 :         Separate( );
    2425         [ #  # ]:          0 :         if (pNode->IsUseLimits())
    2426                 :          0 :             Append( "to " );
    2427                 :            :         else
    2428                 :          0 :             Append( "csup " );
    2429                 :          0 :         LineToText( pChild );
    2430                 :            :     }
    2431                 :          0 : }
    2432                 :            : 
    2433                 :          0 : void SmNodeToTextVisitor::Visit( SmMatrixNode* pNode )
    2434                 :            : {
    2435                 :          0 :     Append( "matrix{" );
    2436         [ #  # ]:          0 :     for ( sal_uInt16 i = 0; i < pNode->GetNumRows( ); i++ ) {
    2437         [ #  # ]:          0 :         for ( sal_uInt16 j = 0; j < pNode->GetNumCols( ); j++ ) {
    2438                 :          0 :             SmNode* pSubNode = pNode->GetSubNode( i * pNode->GetNumCols( ) + j );
    2439                 :          0 :             Separate( );
    2440                 :          0 :             pSubNode->Accept( this );
    2441                 :          0 :             Separate( );
    2442         [ #  # ]:          0 :             if( j != pNode->GetNumCols( ) - 1 )
    2443                 :          0 :                 Append( "#" );
    2444                 :            :         }
    2445                 :          0 :         Separate( );
    2446         [ #  # ]:          0 :         if( i != pNode->GetNumRows( ) - 1 )
    2447                 :          0 :             Append( "##" );
    2448                 :            :     }
    2449                 :          0 :     Append( "} " );
    2450                 :          0 : }
    2451                 :            : 
    2452                 :          0 : void SmNodeToTextVisitor::Visit( SmPlaceNode* )
    2453                 :            : {
    2454                 :          0 :     Append( "<?>" );
    2455                 :          0 : }
    2456                 :            : 
    2457                 :          0 : void SmNodeToTextVisitor::Visit( SmTextNode* pNode )
    2458                 :            : {
    2459                 :            :     //TODO: This method might need improvements, see SmTextNode::CreateTextFromNode
    2460         [ #  # ]:          0 :     if( pNode->GetToken( ).eType == TTEXT )
    2461                 :          0 :         Append( "\"" );
    2462                 :          0 :     Append( pNode->GetText( ) );
    2463         [ #  # ]:          0 :     if( pNode->GetToken( ).eType == TTEXT )
    2464                 :          0 :         Append( "\"" );
    2465                 :          0 : }
    2466                 :            : 
    2467                 :          0 : void SmNodeToTextVisitor::Visit( SmSpecialNode* pNode )
    2468                 :            : {
    2469                 :          0 :     Append( pNode->GetToken( ).aText );
    2470                 :          0 : }
    2471                 :            : 
    2472                 :          0 : void SmNodeToTextVisitor::Visit( SmGlyphSpecialNode* pNode )
    2473                 :            : {
    2474         [ #  # ]:          0 :     if( pNode->GetToken( ).eType == TBOPER )
    2475                 :          0 :         Append( "boper " );
    2476                 :            :     else
    2477                 :          0 :         Append( "uoper " );
    2478                 :          0 :     Append( pNode->GetToken( ).aText );
    2479                 :          0 : }
    2480                 :            : 
    2481                 :          0 : void SmNodeToTextVisitor::Visit( SmMathSymbolNode* pNode )
    2482                 :            : {
    2483                 :          0 :     Append( pNode->GetToken( ).aText );
    2484                 :          0 : }
    2485                 :            : 
    2486                 :          0 : void SmNodeToTextVisitor::Visit( SmBlankNode* pNode )
    2487                 :            : {
    2488                 :          0 :     Append( pNode->GetToken( ).aText );
    2489                 :          0 : }
    2490                 :            : 
    2491                 :          0 : void SmNodeToTextVisitor::Visit( SmErrorNode* )
    2492                 :            : {
    2493                 :          0 : }
    2494                 :            : 
    2495                 :          0 : void SmNodeToTextVisitor::Visit( SmLineNode* pNode )
    2496                 :            : {
    2497         [ #  # ]:          0 :     SmNodeIterator it( pNode );
    2498 [ #  # ][ #  # ]:          0 :     while( it.Next( ) ){
    2499         [ #  # ]:          0 :         Separate( );
    2500         [ #  # ]:          0 :         it->Accept( this );
    2501                 :            :     }
    2502                 :          0 : }
    2503                 :            : 
    2504                 :          0 : void SmNodeToTextVisitor::Visit( SmExpressionNode* pNode )
    2505                 :            : {
    2506 [ #  # ][ #  # ]:          0 :     bool bracketsNeeded = pNode->GetNumSubNodes() != 1 || pNode->GetSubNode(0)->GetType() == NBINHOR;
         [ #  # ][ #  # ]
    2507                 :            :     // nested subsups
    2508                 :            :     bracketsNeeded |=
    2509                 :          0 :         pNode->GetParent()->GetType() == NSUBSUP &&
    2510         [ #  # ]:          0 :         pNode->GetNumSubNodes() == 1 &&
    2511 [ #  # ][ #  # ]:          0 :         pNode->GetSubNode(0)->GetType() == NSUBSUP;
         [ #  # ][ #  # ]
    2512                 :            : 
    2513         [ #  # ]:          0 :     if (bracketsNeeded) {
    2514         [ #  # ]:          0 :         Append( "{ " );
    2515                 :            :     }
    2516         [ #  # ]:          0 :     SmNodeIterator it( pNode );
    2517 [ #  # ][ #  # ]:          0 :     while( it.Next( ) ) {
    2518         [ #  # ]:          0 :         it->Accept( this );
    2519         [ #  # ]:          0 :         Separate( );
    2520                 :            :     }
    2521         [ #  # ]:          0 :     if (bracketsNeeded) {
    2522         [ #  # ]:          0 :         Append( "} " );
    2523                 :            :     }
    2524                 :          0 : }
    2525                 :            : 
    2526                 :          0 : void SmNodeToTextVisitor::Visit( SmPolyLineNode* )
    2527                 :            : {
    2528                 :          0 : }
    2529                 :            : 
    2530                 :          0 : void SmNodeToTextVisitor::Visit( SmRootNode* pNode )
    2531                 :            : {
    2532                 :          0 :     SmNode *pExtra   = pNode->GetSubNode( 0 ),
    2533                 :          0 :            *pBody    = pNode->GetSubNode( 2 );
    2534         [ #  # ]:          0 :     if( pExtra ) {
    2535                 :          0 :         Append( "nroot" );
    2536                 :          0 :         LineToText( pExtra );
    2537                 :            :     } else
    2538                 :          0 :         Append( "sqrt" );
    2539                 :          0 :     LineToText( pBody );
    2540                 :          0 : }
    2541                 :            : 
    2542                 :          0 : void SmNodeToTextVisitor::Visit( SmRootSymbolNode* )
    2543                 :            : {
    2544                 :          0 : }
    2545                 :            : 
    2546                 :          0 : void SmNodeToTextVisitor::Visit( SmRectangleNode* )
    2547                 :            : {
    2548                 :          0 : }
    2549                 :            : 
    2550                 :          0 : void SmNodeToTextVisitor::Visit( SmVerticalBraceNode* pNode )
    2551                 :            : {
    2552                 :          0 :     SmNode *pBody   = pNode->GetSubNode( 0 ),
    2553                 :          0 :            *pScript = pNode->GetSubNode( 2 );
    2554                 :          0 :     LineToText( pBody );
    2555                 :          0 :     Append( pNode->GetToken( ).aText );
    2556                 :          0 :     LineToText( pScript );
    2557 [ +  - ][ +  - ]:         30 : }
    2558                 :            : 
    2559                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10