merge the formfield patch from ooo-build
[ooovba.git] / sc / source / core / tool / reffind.cxx
blob29fa7eea1a3be94af58fa60265702e6fb9cfd6dd
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: reffind.cxx,v $
10 * $Revision: 1.8 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
36 // INCLUDE ---------------------------------------------------------------
38 #include <string.h>
40 #include "reffind.hxx"
41 #include "global.hxx"
42 #include "compiler.hxx"
43 #include "document.hxx"
45 // STATIC DATA -----------------------------------------------------------
47 // incl. Doppelpunkt -> Doppelte Referenzen werden einzeln behandelt
48 const sal_Unicode __FAR_DATA ScRefFinder::pDelimiters[] = {
49 '=','(',')',';','+','-','*','/','^','&',' ','{','}','<','>',':', 0
52 // =======================================================================
54 inline BOOL IsText( sal_Unicode c )
56 return !ScGlobal::UnicodeStrChr( ScRefFinder::pDelimiters, c );
59 inline BOOL IsText( BOOL& bQuote, sal_Unicode c )
61 if ( c == '\'' )
63 bQuote = !bQuote;
64 return TRUE;
66 if ( bQuote )
67 return TRUE;
68 return IsText( c );
71 ScRefFinder::ScRefFinder(const String& rFormula, ScDocument* pDocument,
72 formula::FormulaGrammar::AddressConvention eConvP) :
73 aFormula( rFormula ),
74 eConv( eConvP ),
75 pDoc( pDocument )
77 nSelStart = nSelEnd = nFound = 0;
80 ScRefFinder::~ScRefFinder()
84 USHORT lcl_NextFlags( USHORT nOld )
86 USHORT nNew = nOld & 7; // die drei Abs-Flags
87 nNew = ( nNew - 1 ) & 7; // weiterzaehlen
89 if (!(nOld & SCA_TAB_3D))
90 nNew &= ~SCA_TAB_ABSOLUTE; // nicht 3D -> nie absolut!
92 return ( nOld & 0xfff8 ) | nNew;
95 void ScRefFinder::ToggleRel( xub_StrLen nStartPos, xub_StrLen nEndPos )
97 xub_StrLen nLen = aFormula.Len();
98 if (!nLen)
99 return;
100 const sal_Unicode* pSource = aFormula.GetBuffer(); // fuer schnellen Zugriff
102 // Selektion erweitern, und statt Selektion Start- und Endindex
104 if ( nEndPos < nStartPos )
106 xub_StrLen nTemp = nStartPos; nStartPos = nEndPos; nEndPos = nTemp;
108 while (nStartPos > 0 && IsText(pSource[nStartPos - 1]) )
109 --nStartPos;
110 if (nEndPos)
111 --nEndPos;
112 while (nEndPos+1 < nLen && IsText(pSource[nEndPos + 1]) )
113 ++nEndPos;
115 String aResult;
116 String aExpr;
117 String aSep;
118 ScAddress aAddr;
119 nFound = 0;
121 xub_StrLen nLoopStart = nStartPos;
122 while ( nLoopStart <= nEndPos )
124 // Formel zerlegen
126 xub_StrLen nEStart = nLoopStart;
127 while ( nEStart <= nEndPos && !IsText(pSource[nEStart]) )
128 ++nEStart;
130 BOOL bQuote = FALSE;
131 xub_StrLen nEEnd = nEStart;
132 while ( nEEnd <= nEndPos && IsText(bQuote,pSource[nEEnd]) )
133 ++nEEnd;
135 aSep = aFormula.Copy( nLoopStart, nEStart-nLoopStart );
136 aExpr = aFormula.Copy( nEStart, nEEnd-nEStart );
138 // Test, ob aExpr eine Referenz ist
140 USHORT nResult = aAddr.Parse( aExpr, pDoc, pDoc->GetAddressConvention() );
141 if ( nResult & SCA_VALID )
143 USHORT nFlags = lcl_NextFlags( nResult );
144 aAddr.Format( aExpr, nFlags, pDoc, pDoc->GetAddressConvention() );
146 xub_StrLen nAbsStart = nStartPos+aResult.Len()+aSep.Len();
148 if (!nFound) // erste Referenz ?
149 nSelStart = nAbsStart;
150 nSelEnd = nAbsStart+aExpr.Len(); // Selektion, keine Indizes
151 ++nFound;
154 // zusammenbauen
156 aResult += aSep;
157 aResult += aExpr;
159 nLoopStart = nEEnd;
162 String aTotal = aFormula.Copy( 0, nStartPos );
163 aTotal += aResult;
164 aTotal += aFormula.Copy( nEndPos+1 );
166 aFormula = aTotal;