1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sc.hxx" 30 31 32 33 // INCLUDE --------------------------------------------------------------- 34 35 #include <string.h> 36 37 #include "reffind.hxx" 38 #include "global.hxx" 39 #include "compiler.hxx" 40 #include "document.hxx" 41 42 // STATIC DATA ----------------------------------------------------------- 43 44 // incl. Doppelpunkt -> Doppelte Referenzen werden einzeln behandelt 45 const sal_Unicode __FAR_DATA ScRefFinder::pDelimiters[] = { 46 '=','(',')',';','+','-','*','/','^','&',' ','{','}','<','>',':', 0 47 }; 48 49 // ======================================================================= 50 51 inline sal_Bool IsText( sal_Unicode c ) 52 { 53 return !ScGlobal::UnicodeStrChr( ScRefFinder::pDelimiters, c ); 54 } 55 56 inline sal_Bool IsText( sal_Bool& bQuote, sal_Unicode c ) 57 { 58 if ( c == '\'' ) 59 { 60 bQuote = !bQuote; 61 return sal_True; 62 } 63 if ( bQuote ) 64 return sal_True; 65 return IsText( c ); 66 } 67 68 ScRefFinder::ScRefFinder(const String& rFormula, ScDocument* pDocument, 69 formula::FormulaGrammar::AddressConvention eConvP) : 70 aFormula( rFormula ), 71 eConv( eConvP ), 72 pDoc( pDocument ) 73 { 74 nSelStart = nSelEnd = nFound = 0; 75 } 76 77 ScRefFinder::~ScRefFinder() 78 { 79 } 80 81 sal_uInt16 lcl_NextFlags( sal_uInt16 nOld ) 82 { 83 sal_uInt16 nNew = nOld & 7; // die drei Abs-Flags 84 nNew = ( nNew - 1 ) & 7; // weiterzaehlen 85 86 if (!(nOld & SCA_TAB_3D)) 87 nNew &= ~SCA_TAB_ABSOLUTE; // nicht 3D -> nie absolut! 88 89 return ( nOld & 0xfff8 ) | nNew; 90 } 91 92 void ScRefFinder::ToggleRel( xub_StrLen nStartPos, xub_StrLen nEndPos ) 93 { 94 xub_StrLen nLen = aFormula.Len(); 95 if (!nLen) 96 return; 97 const sal_Unicode* pSource = aFormula.GetBuffer(); // fuer schnellen Zugriff 98 99 // Selektion erweitern, und statt Selektion Start- und Endindex 100 101 if ( nEndPos < nStartPos ) 102 { 103 xub_StrLen nTemp = nStartPos; nStartPos = nEndPos; nEndPos = nTemp; 104 } 105 while (nStartPos > 0 && IsText(pSource[nStartPos - 1]) ) 106 --nStartPos; 107 if (nEndPos) 108 --nEndPos; 109 while (nEndPos+1 < nLen && IsText(pSource[nEndPos + 1]) ) 110 ++nEndPos; 111 112 String aResult; 113 String aExpr; 114 String aSep; 115 ScAddress aAddr; 116 nFound = 0; 117 118 xub_StrLen nLoopStart = nStartPos; 119 while ( nLoopStart <= nEndPos ) 120 { 121 // Formel zerlegen 122 123 xub_StrLen nEStart = nLoopStart; 124 while ( nEStart <= nEndPos && !IsText(pSource[nEStart]) ) 125 ++nEStart; 126 127 sal_Bool bQuote = sal_False; 128 xub_StrLen nEEnd = nEStart; 129 while ( nEEnd <= nEndPos && IsText(bQuote,pSource[nEEnd]) ) 130 ++nEEnd; 131 132 aSep = aFormula.Copy( nLoopStart, nEStart-nLoopStart ); 133 aExpr = aFormula.Copy( nEStart, nEEnd-nEStart ); 134 135 // Test, ob aExpr eine Referenz ist 136 137 sal_uInt16 nResult = aAddr.Parse( aExpr, pDoc, pDoc->GetAddressConvention() ); 138 if ( nResult & SCA_VALID ) 139 { 140 sal_uInt16 nFlags = lcl_NextFlags( nResult ); 141 aAddr.Format( aExpr, nFlags, pDoc, pDoc->GetAddressConvention() ); 142 143 xub_StrLen nAbsStart = nStartPos+aResult.Len()+aSep.Len(); 144 145 if (!nFound) // erste Referenz ? 146 nSelStart = nAbsStart; 147 nSelEnd = nAbsStart+aExpr.Len(); // Selektion, keine Indizes 148 ++nFound; 149 } 150 151 // zusammenbauen 152 153 aResult += aSep; 154 aResult += aExpr; 155 156 nLoopStart = nEEnd; 157 } 158 159 String aTotal = aFormula.Copy( 0, nStartPos ); 160 aTotal += aResult; 161 aTotal += aFormula.Copy( nEndPos+1 ); 162 163 aFormula = aTotal; 164 } 165 166 167 168 169