1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_sc.hxx" 26 27 28 29 // INCLUDE --------------------------------------------------------------- 30 31 #include <string.h> 32 33 #include "reffind.hxx" 34 #include "global.hxx" 35 #include "compiler.hxx" 36 #include "document.hxx" 37 38 // STATIC DATA ----------------------------------------------------------- 39 40 // incl. Doppelpunkt -> Doppelte Referenzen werden einzeln behandelt 41 const sal_Unicode __FAR_DATA ScRefFinder::pDelimiters[] = { 42 '=','(',')',';','+','-','*','/','^','&',' ','{','}','<','>',':', 0 43 }; 44 45 // ======================================================================= 46 47 inline sal_Bool IsText( sal_Unicode c ) 48 { 49 return !ScGlobal::UnicodeStrChr( ScRefFinder::pDelimiters, c ); 50 } 51 52 inline sal_Bool IsText( sal_Bool& bQuote, sal_Unicode c ) 53 { 54 if ( c == '\'' ) 55 { 56 bQuote = !bQuote; 57 return sal_True; 58 } 59 if ( bQuote ) 60 return sal_True; 61 return IsText( c ); 62 } 63 64 ScRefFinder::ScRefFinder(const String& rFormula, ScDocument* pDocument, 65 formula::FormulaGrammar::AddressConvention eConvP) : 66 aFormula( rFormula ), 67 eConv( eConvP ), 68 pDoc( pDocument ) 69 { 70 nSelStart = nSelEnd = nFound = 0; 71 } 72 73 ScRefFinder::~ScRefFinder() 74 { 75 } 76 77 sal_uInt16 lcl_NextFlags( sal_uInt16 nOld ) 78 { 79 sal_uInt16 nNew = nOld & 7; // die drei Abs-Flags 80 nNew = ( nNew - 1 ) & 7; // weiterzaehlen 81 82 if (!(nOld & SCA_TAB_3D)) 83 nNew &= ~SCA_TAB_ABSOLUTE; // nicht 3D -> nie absolut! 84 85 return ( nOld & 0xfff8 ) | nNew; 86 } 87 88 void ScRefFinder::ToggleRel( xub_StrLen nStartPos, xub_StrLen nEndPos ) 89 { 90 xub_StrLen nLen = aFormula.Len(); 91 if (!nLen) 92 return; 93 const sal_Unicode* pSource = aFormula.GetBuffer(); // fuer schnellen Zugriff 94 95 // Selektion erweitern, und statt Selektion Start- und Endindex 96 97 if ( nEndPos < nStartPos ) 98 { 99 xub_StrLen nTemp = nStartPos; nStartPos = nEndPos; nEndPos = nTemp; 100 } 101 while (nStartPos > 0 && IsText(pSource[nStartPos - 1]) ) 102 --nStartPos; 103 if (nEndPos) 104 --nEndPos; 105 while (nEndPos+1 < nLen && IsText(pSource[nEndPos + 1]) ) 106 ++nEndPos; 107 108 String aResult; 109 String aExpr; 110 String aSep; 111 ScAddress aAddr; 112 nFound = 0; 113 114 xub_StrLen nLoopStart = nStartPos; 115 while ( nLoopStart <= nEndPos ) 116 { 117 // Formel zerlegen 118 119 xub_StrLen nEStart = nLoopStart; 120 while ( nEStart <= nEndPos && !IsText(pSource[nEStart]) ) 121 ++nEStart; 122 123 sal_Bool bQuote = sal_False; 124 xub_StrLen nEEnd = nEStart; 125 while ( nEEnd <= nEndPos && IsText(bQuote,pSource[nEEnd]) ) 126 ++nEEnd; 127 128 aSep = aFormula.Copy( nLoopStart, nEStart-nLoopStart ); 129 aExpr = aFormula.Copy( nEStart, nEEnd-nEStart ); 130 131 // Test, ob aExpr eine Referenz ist 132 133 sal_uInt16 nResult = aAddr.Parse( aExpr, pDoc, pDoc->GetAddressConvention() ); 134 if ( nResult & SCA_VALID ) 135 { 136 sal_uInt16 nFlags = lcl_NextFlags( nResult ); 137 aAddr.Format( aExpr, nFlags, pDoc, pDoc->GetAddressConvention() ); 138 139 xub_StrLen nAbsStart = nStartPos+aResult.Len()+aSep.Len(); 140 141 if (!nFound) // erste Referenz ? 142 nSelStart = nAbsStart; 143 nSelEnd = nAbsStart+aExpr.Len(); // Selektion, keine Indizes 144 ++nFound; 145 } 146 147 // zusammenbauen 148 149 aResult += aSep; 150 aResult += aExpr; 151 152 nLoopStart = nEEnd; 153 } 154 155 String aTotal = aFormula.Copy( 0, nStartPos ); 156 aTotal += aResult; 157 aTotal += aFormula.Copy( nEndPos+1 ); 158 159 aFormula = aTotal; 160 } 161 162 163 164 165