LibreOffice Module sc (master)  1
xihelper.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <memory>
21 #include <xihelper.hxx>
22 #include <svl/itemset.hxx>
23 #include <svl/sharedstringpool.hxx>
24 #include <editeng/editobj.hxx>
25 #include <tools/urlobj.hxx>
26 #include <editeng/eeitem.hxx>
27 #include <editeng/flditem.hxx>
28 #include <document.hxx>
29 #include <rangelst.hxx>
30 #include <editutil.hxx>
31 #include <attrib.hxx>
32 #include <xltracer.hxx>
33 #include <xistream.hxx>
34 #include <xistring.hxx>
35 #include <xistyle.hxx>
36 #include <excform.hxx>
37 #include <scmatrix.hxx>
38 #include <documentimport.hxx>
39 #include <sal/log.hxx>
40 
41 // Excel->Calc cell address/range conversion ==================================
42 
43 namespace {
44 
46 void lclFillAddress( ScAddress& rScPos, sal_uInt16 nXclCol, sal_uInt32 nXclRow, SCTAB nScTab )
47 {
48  rScPos.SetCol( static_cast< SCCOL >( nXclCol ) );
49  rScPos.SetRow( static_cast< SCROW >( nXclRow ) );
50  rScPos.SetTab( nScTab );
51 }
52 
53 } // namespace
54 
56  XclAddressConverterBase( rRoot.GetTracer(), rRoot.GetScMaxPos() )
57 {
58 }
59 
60 // cell address ---------------------------------------------------------------
61 
62 bool XclImpAddressConverter::CheckAddress( const XclAddress& rXclPos, bool bWarn )
63 {
64  bool bValidCol = rXclPos.mnCol <= mnMaxCol;
65  bool bValidRow = rXclPos.mnRow <= mnMaxRow;
66  bool bValid = bValidCol && bValidRow;
67  if( !bValid && bWarn )
68  {
69  mbColTrunc |= !bValidCol;
70  mbRowTrunc |= !bValidRow;
72  static_cast< SCCOL >( rXclPos.mnCol ), static_cast< SCROW >( rXclPos.mnRow ), 0 ), maMaxPos );
73  }
74  return bValid;
75 }
76 
78  const XclAddress& rXclPos, SCTAB nScTab, bool bWarn )
79 {
80  bool bValid = CheckAddress( rXclPos, bWarn );
81  if( bValid )
82  lclFillAddress( rScPos, rXclPos.mnCol, rXclPos.mnRow, nScTab );
83  return bValid;
84 }
85 
87  const XclAddress& rXclPos, SCTAB nScTab, bool bWarn )
88 {
90  if( !ConvertAddress( aScPos, rXclPos, nScTab, bWarn ) )
91  {
92  aScPos.SetCol( static_cast< SCCOL >( ::std::min( rXclPos.mnCol, mnMaxCol ) ) );
93  aScPos.SetRow( static_cast< SCROW >( ::std::min( rXclPos.mnRow, mnMaxRow ) ) );
94  aScPos.SetTab( limit_cast< SCTAB >( nScTab, 0, maMaxPos.Tab() ) );
95  }
96  return aScPos;
97 }
98 
99 // cell range -----------------------------------------------------------------
100 
102  const XclRange& rXclRange, SCTAB nScTab1, SCTAB nScTab2, bool bWarn )
103 {
104  // check start position
105  bool bValidStart = CheckAddress( rXclRange.maFirst, bWarn );
106  if( bValidStart )
107  {
108  lclFillAddress( rScRange.aStart, rXclRange.maFirst.mnCol, rXclRange.maFirst.mnRow, nScTab1 );
109 
110  // check & correct end position
111  sal_uInt16 nXclCol2 = rXclRange.maLast.mnCol;
112  sal_uInt32 nXclRow2 = rXclRange.maLast.mnRow;
113  if( !CheckAddress( rXclRange.maLast, bWarn ) )
114  {
115  nXclCol2 = ::std::min( nXclCol2, mnMaxCol );
116  nXclRow2 = ::std::min( nXclRow2, mnMaxRow );
117  }
118  lclFillAddress( rScRange.aEnd, nXclCol2, nXclRow2, nScTab2 );
119  }
120  return bValidStart;
121 }
122 
123 // cell range list ------------------------------------------------------------
124 
126  const XclRangeList& rXclRanges, SCTAB nScTab, bool bWarn )
127 {
128  rScRanges.RemoveAll();
129  for( const auto& rXclRange : rXclRanges )
130  {
131  ScRange aScRange( ScAddress::UNINITIALIZED );
132  if( ConvertRange( aScRange, rXclRange, nScTab, nScTab, bWarn ) )
133  rScRanges.push_back( aScRange );
134  }
135 }
136 
137 // String->EditEngine conversion ==============================================
138 
139 namespace {
140 
141 std::unique_ptr<EditTextObject> lclCreateTextObject( const XclImpRoot& rRoot,
142  const XclImpString& rString, XclFontItemType eType, sal_uInt16 nXFIndex )
143 {
144  std::unique_ptr<EditTextObject> pTextObj;
145 
146  const XclImpXFBuffer& rXFBuffer = rRoot.GetXFBuffer();
147  const XclImpFont* pFirstFont = rXFBuffer.GetFont( nXFIndex );
148  bool bFirstEscaped = pFirstFont && pFirstFont->HasEscapement();
149 
150  if( rString.IsRich() || bFirstEscaped )
151  {
152  const XclImpFontBuffer& rFontBuffer = rRoot.GetFontBuffer();
153  const XclFormatRunVec& rFormats = rString.GetFormats();
154 
155  ScEditEngineDefaulter& rEE = rRoot.GetEditEngine();
156  rEE.SetTextCurrentDefaults( rString.GetText() );
157 
158  SfxItemSet aItemSet( rEE.GetEmptyItemSet() );
159  if( bFirstEscaped )
160  rFontBuffer.FillToItemSet( aItemSet, eType, rXFBuffer.GetFontIndex( nXFIndex ) );
161  ESelection aSelection;
162 
163  XclFormatRun aNextRun;
164  XclFormatRunVec::const_iterator aIt = rFormats.begin();
165  XclFormatRunVec::const_iterator aEnd = rFormats.end();
166 
167  if( aIt != aEnd )
168  aNextRun = *aIt++;
169  else
170  aNextRun.mnChar = 0xFFFF;
171 
172  sal_Int32 nLen = rString.GetText().getLength();
173  for( sal_Int32 nChar = 0; nChar < nLen; ++nChar )
174  {
175  // reached new different formatted text portion
176  if( nChar >= aNextRun.mnChar )
177  {
178  // send items to edit engine
179  rEE.QuickSetAttribs( aItemSet, aSelection );
180 
181  // start new item set
182  aItemSet.ClearItem();
183  rFontBuffer.FillToItemSet( aItemSet, eType, aNextRun.mnFontIdx );
184 
185  // read new formatting information
186  if( aIt != aEnd )
187  aNextRun = *aIt++;
188  else
189  aNextRun.mnChar = 0xFFFF;
190 
191  // reset selection start to current position
192  aSelection.nStartPara = aSelection.nEndPara;
193  aSelection.nStartPos = aSelection.nEndPos;
194  }
195 
196  // set end of selection to current position
197  if( rString.GetText()[ nChar ] == '\n' )
198  {
199  ++aSelection.nEndPara;
200  aSelection.nEndPos = 0;
201  }
202  else
203  ++aSelection.nEndPos;
204  }
205 
206  // send items of last text portion to edit engine
207  rEE.QuickSetAttribs( aItemSet, aSelection );
208 
209  pTextObj = rEE.CreateTextObject();
210  }
211 
212  return pTextObj;
213 }
214 
215 } // namespace
216 
217 std::unique_ptr<EditTextObject> XclImpStringHelper::CreateTextObject(
218  const XclImpRoot& rRoot, const XclImpString& rString )
219 {
220  return lclCreateTextObject( rRoot, rString, XclFontItemType::Editeng, 0 );
221 }
222 
224  ScDocumentImport& rDoc, const ScAddress& rPos, const XclImpRoot& rRoot,
225  const XclImpString& rString, sal_uInt16 nXFIndex )
226 {
227  if (rString.GetText().isEmpty())
228  return;
229 
230  ::std::unique_ptr< EditTextObject > pTextObj( lclCreateTextObject( rRoot, rString, XclFontItemType::Editeng, nXFIndex ) );
231 
232  if (pTextObj)
233  {
234  rDoc.setEditCell(rPos, std::move(pTextObj));
235  }
236  else
237  {
238  const OUString& aStr = rString.GetText();
239  if (aStr.indexOf('\n') != -1 || aStr.indexOf('\r') != -1)
240  {
241  // Multiline content.
242  ScFieldEditEngine& rEngine = rDoc.getDoc().GetEditEngine();
243  rEngine.SetTextCurrentDefaults(aStr);
244  rDoc.setEditCell(rPos, rEngine.CreateTextObject());
245  }
246  else
247  {
248  // Normal text cell.
249  rDoc.setStringCell(rPos, aStr);
250  }
251  }
252 }
253 
254 // Header/footer conversion ===================================================
255 
257  mnHeight( 0 ),
258  mnMaxLineHt( 0 )
259 {
262 }
263 
265  XclImpRoot( rRoot ),
266  mrEE( rRoot.GetHFEditEngine() ),
267  mxFontData( new XclFontData ),
269 {
270 }
271 
273 {
274 }
275 
276 void XclImpHFConverter::ParseString( const OUString& rHFString )
277 {
278  // edit engine objects
280  maInfos.clear();
281  maInfos.resize( EXC_HF_PORTION_COUNT );
283 
284  // parser temporaries
285  maCurrText.truncate();
286  OUStringBuffer aReadFont; // current font name
287  OUStringBuffer aReadStyle; // current font style
288  sal_uInt16 nReadHeight = 0; // current font height
289  ResetFontData();
290 
292  enum XclHFParserState
293  {
294  xlPSText,
295  xlPSFunc,
296  xlPSFont,
297  xlPSFontStyle,
298  xlPSHeight
299  } eState = xlPSText;
300 
301  const sal_Unicode* pChar = rHFString.getStr();
302  const sal_Unicode* pNull = pChar + rHFString.getLength(); // pointer to terminating null char
303  while( *pChar )
304  {
305  switch( eState )
306  {
307 
308 // --- read text character ---
309 
310  case xlPSText:
311  {
312  switch( *pChar )
313  {
314  case '&': // new command
315  InsertText();
316  eState = xlPSFunc;
317  break;
318  case '\n': // line break
319  InsertText();
320  InsertLineBreak();
321  break;
322  default:
323  maCurrText.append(OUStringChar(*pChar));
324  }
325  }
326  break;
327 
328 // --- read control sequence ---
329 
330  case xlPSFunc:
331  {
332  eState = xlPSText;
333  switch( *pChar )
334  {
335  case '&': maCurrText.append("&"); break; // the '&' character
336 
337  case 'L': SetNewPortion( EXC_HF_LEFT ); break; // Left portion
338  case 'C': SetNewPortion( EXC_HF_CENTER ); break; // Center portion
339  case 'R': SetNewPortion( EXC_HF_RIGHT ); break; // Right portion
340 
341  case 'P': InsertField( SvxFieldItem( SvxPageField(), EE_FEATURE_FIELD ) ); break; // page
342  case 'N': InsertField( SvxFieldItem( SvxPagesField(), EE_FEATURE_FIELD ) ); break; // page count
343  case 'D': InsertField( SvxFieldItem( SvxDateField(), EE_FEATURE_FIELD ) ); break; // date
344  case 'T': InsertField( SvxFieldItem( SvxTimeField(), EE_FEATURE_FIELD ) ); break; // time
345  case 'A': InsertField( SvxFieldItem( SvxTableField(), EE_FEATURE_FIELD ) ); break; // table name
346 
347  case 'Z': // file path
348  InsertField( SvxFieldItem( SvxExtFileField(), EE_FEATURE_FIELD ) ); // convert to full name
349  if( (pNull - pChar >= 2) && (*(pChar + 1) == '&') && (*(pChar + 2) == 'F') )
350  {
351  // &Z&F found - ignore the &F part
352  pChar += 2;
353  }
354  break;
355  case 'F': // file name
356  InsertField( SvxFieldItem( SvxExtFileField( EMPTY_OUSTRING, SvxFileType::Var, SvxFileFormat::NameAndExt ), EE_FEATURE_FIELD ) );
357  break;
358 
359  case 'U': // underline
360  SetAttribs();
361  mxFontData->mnUnderline = (mxFontData->mnUnderline == EXC_FONTUNDERL_SINGLE) ?
363  break;
364  case 'E': // double underline
365  SetAttribs();
366  mxFontData->mnUnderline = (mxFontData->mnUnderline == EXC_FONTUNDERL_DOUBLE) ?
368  break;
369  case 'S': // strikeout
370  SetAttribs();
371  mxFontData->mbStrikeout = !mxFontData->mbStrikeout;
372  break;
373  case 'X': // superscript
374  SetAttribs();
375  mxFontData->mnEscapem = (mxFontData->mnEscapem == EXC_FONTESC_SUPER) ?
377  break;
378  case 'Y': // subsrcipt
379  SetAttribs();
380  mxFontData->mnEscapem = (mxFontData->mnEscapem == EXC_FONTESC_SUB) ?
382  break;
383 
384  case '\"': // font name
385  aReadFont.setLength(0);
386  aReadStyle.setLength(0);
387  eState = xlPSFont;
388  break;
389  default:
390  if( ('0' <= *pChar) && (*pChar <= '9') ) // font size
391  {
392  nReadHeight = *pChar - '0';
393  eState = xlPSHeight;
394  }
395  }
396  }
397  break;
398 
399 // --- read font name ---
400 
401  case xlPSFont:
402  {
403  switch( *pChar )
404  {
405  case '\"':
406  --pChar;
407  [[fallthrough]];
408  case ',':
409  eState = xlPSFontStyle;
410  break;
411  default:
412  aReadFont.append(*pChar);
413  }
414  }
415  break;
416 
417 // --- read font style ---
418 
419  case xlPSFontStyle:
420  {
421  switch( *pChar )
422  {
423  case '\"':
424  SetAttribs();
425  if( !aReadFont.isEmpty() )
426  mxFontData->maName = aReadFont.toString();
427  mxFontData->maStyle = aReadStyle.toString();
428  eState = xlPSText;
429  break;
430  default:
431  aReadStyle.append(*pChar);
432  }
433  }
434  break;
435 
436 // --- read font height ---
437 
438  case xlPSHeight:
439  {
440  if( ('0' <= *pChar) && (*pChar <= '9') )
441  {
442  if( nReadHeight != 0xFFFF )
443  {
444  nReadHeight *= 10;
445  nReadHeight += (*pChar - '0');
446  if( nReadHeight > 1600 ) // max 1600pt = 32000twips
447  nReadHeight = 0xFFFF;
448  }
449  }
450  else
451  {
452  if( (nReadHeight != 0) && (nReadHeight != 0xFFFF) )
453  {
454  SetAttribs();
455  mxFontData->mnHeight = nReadHeight * 20;
456  }
457  --pChar;
458  eState = xlPSText;
459  }
460  }
461  break;
462  }
463  ++pChar;
464  }
465 
466  // finalize
471 }
472 
473 void XclImpHFConverter::FillToItemSet( SfxItemSet& rItemSet, sal_uInt16 nWhichId ) const
474 {
475  ScPageHFItem aHFItem( nWhichId );
476  if( maInfos[ EXC_HF_LEFT ].mxObj )
477  aHFItem.SetLeftArea( *maInfos[ EXC_HF_LEFT ].mxObj );
478  if( maInfos[ EXC_HF_CENTER ].mxObj )
479  aHFItem.SetCenterArea( *maInfos[ EXC_HF_CENTER ].mxObj );
480  if( maInfos[ EXC_HF_RIGHT ].mxObj )
481  aHFItem.SetRightArea( *maInfos[ EXC_HF_RIGHT ].mxObj );
482  rItemSet.Put( aHFItem );
483 }
484 
486 {
487  return ::std::max( maInfos[ EXC_HF_LEFT ].mnHeight,
488  ::std::max( maInfos[ EXC_HF_CENTER ].mnHeight, maInfos[ EXC_HF_RIGHT ].mnHeight ) );
489 }
490 
491 // private --------------------------------------------------------------------
492 
494 {
495  sal_uInt16 nMaxHt = maInfos[ ePortion ].mnMaxLineHt;
496  return (nMaxHt == 0) ? mxFontData->mnHeight : nMaxHt;
497 }
498 
500 {
501  sal_uInt16& rnMaxHt = maInfos[ ePortion ].mnMaxLineHt;
502  rnMaxHt = ::std::max( rnMaxHt, mxFontData->mnHeight );
503 }
504 
506 {
508 }
509 
511 {
512  ESelection& rSel = GetCurrSel();
513  if( (rSel.nStartPara != rSel.nEndPara) || (rSel.nStartPos != rSel.nEndPos) )
514  {
515  SfxItemSet aItemSet( mrEE.GetEmptyItemSet() );
516  XclImpFont aFont( GetRoot(), *mxFontData );
517  aFont.FillToItemSet( aItemSet, XclFontItemType::HeaderFooter );
518  mrEE.QuickSetAttribs( aItemSet, rSel );
519  rSel.nStartPara = rSel.nEndPara;
520  rSel.nStartPos = rSel.nEndPos;
521  }
522 }
523 
525 {
526  if( const XclImpFont* pFirstFont = GetFontBuffer().GetFont( EXC_FONT_APP ) )
527  *mxFontData = pFirstFont->GetFontData();
528  else
529  {
530  mxFontData->Clear();
531  mxFontData->mnHeight = 200;
532  }
533 }
534 
536 {
537  if( !maCurrText.isEmpty() )
538  {
539  ESelection& rSel = GetCurrSel();
540  OUString sString(maCurrText.makeStringAndClear());
541  mrEE.QuickInsertText( sString, ESelection( rSel.nEndPara, rSel.nEndPos, rSel.nEndPara, rSel.nEndPos ) );
542  rSel.nEndPos = rSel.nEndPos + sString.getLength();
544  }
545 }
546 
548 {
549  ESelection& rSel = GetCurrSel();
550  mrEE.QuickInsertField( rFieldItem, ESelection( rSel.nEndPara, rSel.nEndPos, rSel.nEndPara, rSel.nEndPos ) );
551  ++rSel.nEndPos;
553 }
554 
556 {
557  ESelection& rSel = GetCurrSel();
558  mrEE.QuickInsertText( OUString('\n'), ESelection( rSel.nEndPara, rSel.nEndPos, rSel.nEndPara, rSel.nEndPos ) );
559  ++rSel.nEndPara;
560  rSel.nEndPos = 0;
562  GetCurrInfo().mnMaxLineHt = 0;
563 }
564 
566 {
567  InsertText();
568  SetAttribs();
570 }
571 
573 {
574  if( eNew != meCurrObj )
575  {
577  meCurrObj = eNew;
578  if( GetCurrObj() )
579  mrEE.SetText( *GetCurrObj() );
580  else
582  ResetFontData();
583  }
584 }
585 
586 // URL conversion =============================================================
587 
588 namespace {
589 
590 void lclAppendUrlChar( OUString& rUrl, sal_Unicode cChar )
591 {
592  // encode special characters
593  switch( cChar )
594  {
595  case '#': rUrl += "%23"; break;
596  case '%': rUrl += "%25"; break;
597  default: rUrl += OUStringChar( cChar );
598  }
599 }
600 
601 } // namespace
602 
604  OUString& rUrl, OUString& rTabName, bool& rbSameWb,
605  const XclImpRoot& rRoot, const OUString& rEncodedUrl )
606 {
607  enum
608  {
609  xlUrlInit,
610  xlUrlPath,
611  xlUrlFileName,
612  xlUrlSheetName,
613  xlUrlRaw
614  } eState = xlUrlInit;
615 
616  bool bEncoded = true;
617  rbSameWb = false;
618 
619  sal_Unicode cCurrDrive = 0;
620  OUString aDosBase( INetURLObject( rRoot.GetBasePath() ).getFSysPath( FSysStyle::Dos ) );
621  if (!aDosBase.isEmpty() && aDosBase.match(":\\", 1))
622  cCurrDrive = aDosBase[0];
623 
624  const sal_Unicode* pChar = rEncodedUrl.getStr();
625  while( *pChar )
626  {
627  switch( eState )
628  {
629 
630 // --- first character ---
631 
632  case xlUrlInit:
633  {
634  switch( *pChar )
635  {
637  eState = xlUrlPath;
638  break;
639  case EXC_URLSTART_SELF:
641  rbSameWb = true;
642  eState = xlUrlSheetName;
643  break;
644  case '[':
645  bEncoded = false;
646  eState = xlUrlFileName;
647  break;
648  default:
649  bEncoded = false;
650  lclAppendUrlChar( rUrl, *pChar );
651  eState = xlUrlPath;
652  }
653  }
654  break;
655 
656 // --- URL path ---
657 
658  case xlUrlPath:
659  {
660  switch( *pChar )
661  {
662  case EXC_URL_DOSDRIVE:
663  {
664  if( *(pChar + 1) )
665  {
666  ++pChar;
667  if( *pChar == '@' )
668  rUrl += "\\\\";
669  else
670  {
671  lclAppendUrlChar( rUrl, *pChar );
672  rUrl += ":\\";
673  }
674  }
675  else
676  rUrl += "<NULL-DRIVE!>";
677  }
678  break;
679  case EXC_URL_DRIVEROOT:
680  if( cCurrDrive )
681  {
682  lclAppendUrlChar( rUrl, cCurrDrive );
683  rUrl += ":";
684  }
685  [[fallthrough]];
686  case EXC_URL_SUBDIR:
687  if( bEncoded )
688  rUrl += "\\";
689  else // control character in raw name -> DDE link
690  {
691  rUrl += OUStringChar(EXC_DDE_DELIM);
692  eState = xlUrlRaw;
693  }
694  break;
695  case EXC_URL_PARENTDIR:
696  rUrl += "..\\";
697  break;
698  case EXC_URL_RAW:
699  {
700  if( *(pChar + 1) )
701  {
702  sal_Int32 nLen = *++pChar;
703  for( sal_Int32 nChar = 0; (nChar < nLen) && *(pChar + 1); ++nChar )
704  lclAppendUrlChar( rUrl, *++pChar );
705 // rUrl.Append( ':' );
706  }
707  }
708  break;
709  case '[':
710  eState = xlUrlFileName;
711  break;
712  default:
713  lclAppendUrlChar( rUrl, *pChar );
714  }
715  }
716  break;
717 
718 // --- file name ---
719 
720  case xlUrlFileName:
721  {
722  switch( *pChar )
723  {
724  case ']': eState = xlUrlSheetName; break;
725  default: lclAppendUrlChar( rUrl, *pChar );
726  }
727  }
728  break;
729 
730 // --- sheet name ---
731 
732  case xlUrlSheetName:
733  rTabName += OUStringChar( *pChar );
734  break;
735 
736 // --- raw read mode ---
737 
738  case xlUrlRaw:
739  lclAppendUrlChar( rUrl, *pChar );
740  break;
741  }
742 
743  ++pChar;
744  }
745 }
746 
748  OUString& rUrl, bool& rbSameWb, const XclImpRoot& rRoot, const OUString& rEncodedUrl )
749 {
750  OUString aTabName;
751  OUString aUrl;
752  DecodeUrl( aUrl, aTabName, rbSameWb, rRoot, rEncodedUrl );
753  rUrl = aUrl;
754  OSL_ENSURE( aTabName.isEmpty(), "XclImpUrlHelper::DecodeUrl - sheet name ignored" );
755 }
756 
757 bool XclImpUrlHelper::DecodeLink( OUString& rApplic, OUString& rTopic, const OUString& rEncUrl )
758 {
759  sal_Int32 nPos = rEncUrl.indexOf( EXC_DDE_DELIM );
760  if( (nPos > 0) && (nPos + 1 < rEncUrl.getLength()) )
761  {
762  rApplic = rEncUrl.copy( 0, nPos );
763  rTopic = rEncUrl.copy( nPos + 1 );
764  return true;
765  }
766  return false;
767 }
768 
769 // Cached Values ==============================================================
770 
772  mfValue( 0.0 ),
773  mnBoolErr( 0 )
774 {
775  mnType = rStrm.ReaduInt8();
776  switch( mnType )
777  {
778  case EXC_CACHEDVAL_EMPTY:
779  rStrm.Ignore( 8 );
780  break;
782  mfValue = rStrm.ReadDouble();
783  break;
785  maStr = rStrm.ReadUniString();
786  break;
787  case EXC_CACHEDVAL_BOOL:
788  case EXC_CACHEDVAL_ERROR:
789  {
790  double fVal;
791  mnBoolErr = rStrm.ReaduInt8();
792  rStrm.Ignore( 7 );
793 
794  std::unique_ptr<ScTokenArray> pScTokArr = rStrm.GetRoot().GetOldFmlaConverter().GetBoolErr(
796  if( pScTokArr )
797  mxTokArr = std::move( pScTokArr );
798  }
799  break;
800  default:
801  OSL_FAIL( "XclImpCachedValue::XclImpCachedValue - unknown data type" );
802  }
803 }
804 
806 {
807 }
808 
810 {
811  return (mnType == EXC_CACHEDVAL_ERROR) ? XclTools::GetScErrorCode( mnBoolErr ) : FormulaError::NONE;
812 }
813 
814 // Matrix Cached Values ==============================================================
815 
817  mnScCols( 0 ),
818  mnScRows( 0 )
819 {
820  mnScCols = rStrm.ReaduInt8();
821  mnScRows = rStrm.ReaduInt16();
822 
823  if( rStrm.GetRoot().GetBiff() <= EXC_BIFF5 )
824  {
825  // in BIFF2-BIFF7: 256 columns represented by 0 columns
826  if( mnScCols == 0 )
827  mnScCols = 256;
828  }
829  else
830  {
831  // in BIFF8: columns and rows decreaed by 1
832  ++mnScCols;
833  ++mnScRows;
834  }
835 
836  //assuming worst case scenario of unknown types
837  const size_t nMinRecordSize = 1;
838  const size_t nMaxRows = rStrm.GetRecLeft() / (nMinRecordSize * mnScCols);
839  if (mnScRows > nMaxRows)
840  {
841  SAL_WARN("sc", "Parsing error: " << nMaxRows <<
842  " max possible rows, but " << mnScRows << " claimed, truncating");
843  mnScRows = nMaxRows;
844  }
845 
846  for( SCSIZE nScRow = 0; nScRow < mnScRows; ++nScRow )
847  for( SCSIZE nScCol = 0; nScCol < mnScCols; ++nScCol )
848  maValueList.push_back( std::make_unique<XclImpCachedValue>( rStrm ) );
849 }
850 
852 {
853 }
854 
856 {
857  ScMatrixRef xScMatrix;
858  OSL_ENSURE( mnScCols * mnScRows == maValueList.size(), "XclImpCachedMatrix::CreateScMatrix - element count mismatch" );
859  if( mnScCols && mnScRows && static_cast< sal_uLong >( mnScCols * mnScRows ) <= maValueList.size() )
860  {
861  xScMatrix = new ScMatrix(mnScCols, mnScRows, 0.0);
862  XclImpValueList::const_iterator itValue = maValueList.begin();
863  for( SCSIZE nScRow = 0; nScRow < mnScRows; ++nScRow )
864  {
865  for( SCSIZE nScCol = 0; nScCol < mnScCols; ++nScCol )
866  {
867  switch( (*itValue)->GetType() )
868  {
869  case EXC_CACHEDVAL_EMPTY:
870  // Excel shows 0.0 here, not an empty cell
871  xScMatrix->PutEmpty( nScCol, nScRow );
872  break;
874  xScMatrix->PutDouble( (*itValue)->GetValue(), nScCol, nScRow );
875  break;
877  xScMatrix->PutString(rPool.intern((*itValue)->GetString()), nScCol, nScRow);
878  break;
879  case EXC_CACHEDVAL_BOOL:
880  xScMatrix->PutBoolean( (*itValue)->GetBool(), nScCol, nScRow );
881  break;
882  case EXC_CACHEDVAL_ERROR:
883  xScMatrix->PutError( (*itValue)->GetScError(), nScCol, nScRow );
884  break;
885  default:
886  OSL_FAIL( "XclImpCachedMatrix::CreateScMatrix - unknown value type" );
887  xScMatrix->PutEmpty( nScCol, nScRow );
888  }
889  ++itValue;
890  }
891  }
892  }
893  return xScMatrix;
894 }
895 
896 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
ScAddress maMaxPos
Tracer for invalid addresses.
Definition: xladdress.hxx:161
virtual ~XclImpCachedValue()
Definition: xihelper.cxx:805
Matrix data type that can store values of mixed types.
Definition: scmatrix.hxx:113
const sal_Unicode EXC_URLSTART_SELF
Encoded URL.
Definition: xlconst.hxx:90
Use edit engine Which-IDs (EE_CHAR_*).
double mnHeight
sal_uInt16 mnMaxLineHt
Height of previous lines in twips.
Definition: xihelper.hxx:196
const sal_Unicode EXC_URL_PARENTDIR
Directory name delimiter.
Definition: xlconst.hxx:97
static std::unique_ptr< EditTextObject > CreateTextObject(const XclImpRoot &rRoot, const XclImpString &rString)
Returns a new edit engine text object.
Definition: xihelper.cxx:217
sal_Int32 nStartPara
static bool DecodeLink(OUString &rApplic, OUString &rTopic, const OUString &rEncUrl)
Decodes the passed URL to OLE or DDE link components.
Definition: xihelper.cxx:757
ScAddress aStart
Definition: address.hxx:500
const XclImpFont * GetFont(sal_uInt16 nXFIndex) const
Returns the Excel font used in the specified XF record.
Definition: xistyle.cxx:1591
SharedString intern(const OUString &rStr)
void InsertLineBreak()
Inserts a line break and adjusts the current selection object.
Definition: xihelper.cxx:555
Contains all XF records occurred in the file.
Definition: xistyle.hxx:478
static XclBoolError ErrorToEnum(double &rfDblValue, bool bErrOrBool, sal_uInt8 nValue)
Gets a translated error code or Boolean value from Excel error codes.
Definition: xltools.cxx:244
#define EMPTY_OUSTRING
Definition: global.hxx:214
SCSIZE mnScCols
List of cached cell values.
Definition: xihelper.hxx:347
XclImpHFPortionInfo()
Maximum font height for the current text line.
Definition: xihelper.cxx:256
Stores all data of an Excel font and provides import of FONT records.
Definition: xistyle.hxx:71
const SfxItemSet & GetEmptyItemSet() const
EditEngine & mrEE
Definition: xihelper.hxx:239
XclFontDataPtr mxFontData
Current text to insert into edit engine.
Definition: xihelper.hxx:243
void SetAttribs()
Sets the font attributes at the current selection.
Definition: xihelper.cxx:510
sal_uInt16 mnMaxCol
Default maximum position.
Definition: xladdress.hxx:162
void ResetFontData()
Resets font data to application default font.
Definition: xihelper.cxx:524
void QuickInsertField(const SvxFieldItem &rFld, const ESelection &rSel)
sal_uInt16 GetMaxLineHeight(XclImpHFPortion ePortion) const
Returns the maximum line height of the specified portion.
Definition: xihelper.cxx:493
This struct helps reading and writing Excel fonts.
Definition: xlstyle.hxx:286
sal_uInt8 mnType
Boolean value or Excel error code.
Definition: xihelper.hxx:330
void ConvertRangeList(ScRangeList &rScRanges, const XclRangeList &rXclRanges, SCTAB nScTab, bool bWarn)
Converts the passed Excel cell range list to a Calc cell range list.
Definition: xihelper.cxx:125
ScAddress aEnd
Definition: address.hxx:501
XclAddress maLast
Definition: xladdress.hxx:61
sal_uInt32 mnRow
Definition: xladdress.hxx:33
const XclFormatRunVec & GetFormats() const
Returns the formatting run vector.
Definition: xistring.hxx:59
Use Calc Which-IDs (ATTR_*).
bool IsRich() const
Returns true, if the string contains formatting information.
Definition: xistring.hxx:57
XclAddress maFirst
Definition: xladdress.hxx:60
const sal_uInt8 EXC_CACHEDVAL_ERROR
Definition: xlconst.hxx:119
const sal_Unicode EXC_URLSTART_ENCODED
Definition: xlconst.hxx:89
Accessor class to ScDocument.
bool HasEscapement() const
Returns true, if the font contains superscript or subscript.
Definition: xistyle.hxx:91
static void SetToDocument(ScDocumentImport &rDoc, const ScAddress &rPos, const XclImpRoot &rRoot, const XclImpString &rString, sal_uInt16 nXFIndex)
Definition: xihelper.cxx:223
virtual ~XclImpHFConverter() override
Definition: xihelper.cxx:272
const XclImpRoot & GetRoot() const
Returns this root instance - for code readability in derived classes.
Definition: xiroot.hxx:132
void FillToItemSet(SfxItemSet &rItemSet, XclFontItemType eType, sal_uInt16 nFontIdx, bool bSkipPoolDefs=false) const
Fills all font properties from a FONT record to the item set.
Definition: xistyle.cxx:592
void setEditCell(const ScAddress &rPos, std::unique_ptr< EditTextObject > pEditText)
void SetNewPortion(XclImpHFPortion eNew)
Changes current header/footer portion to eNew.
Definition: xihelper.cxx:572
void SetLeftArea(const EditTextObject &rNew)
Definition: attrib.cxx:472
const sal_uInt16 EXC_FONTESC_SUB
Definition: xlstyle.hxx:128
sal_uInt32 mnMaxRow
Maximum column index, as 16-bit value.
Definition: xladdress.hxx:163
const sal_Unicode EXC_DDE_DELIM
Sheet name starts here (BIFF4).
Definition: xlconst.hxx:101
sal_uInt16 sal_Unicode
const sal_uInt16 EXC_FONT_APP
Definition: xlstyle.hxx:77
void SetText(const OUString &rStr)
MS Excel 4.0.
Definition: xlconst.hxx:35
size_t SCSIZE
size_t typedef to be able to find places where code was changed from USHORT to size_t and is used to ...
Definition: address.hxx:45
void SetCenterArea(const EditTextObject &rNew)
Definition: attrib.cxx:477
ScMatrixRef CreateScMatrix(svl::SharedStringPool &rPool) const
Creates a new ScMatrix object and fills it with the contained values.
Definition: xihelper.cxx:855
NUL character (unicode).
Definition: xlstring.hxx:64
void UpdateMaxLineHeight(XclImpHFPortion ePortion)
Updates the maximum line height of the specified portion, using the current font size.
Definition: xihelper.cxx:499
static FormulaError GetScErrorCode(sal_uInt8 nXclError)
Converts an Excel error code to a Calc error code.
Definition: xltools.cxx:223
ExcelToSc & GetOldFmlaConverter() const
Returns the old formula converter.
Definition: xiroot.cxx:129
void push_back(const ScRange &rRange)
Definition: rangelst.cxx:1144
void ParseString(const OUString &rHFString)
Parses the passed string and creates three new edit engine text objects.
Definition: xihelper.cxx:276
const sal_uInt16 EXC_FONTESC_NONE
Definition: xlstyle.hxx:126
::boost::intrusive_ptr< ScMatrix > ScMatrixRef
Definition: types.hxx:26
SCTAB Tab() const
Definition: address.hxx:271
void SetRow(SCROW nRowP)
Definition: address.hxx:275
::std::vector< XclFormatRun > XclFormatRunVec
A vector with all formatting runs for a rich-string.
Definition: xlstring.hxx:85
XclImpXFBuffer & GetXFBuffer() const
Returns the cell formatting attributes buffer.
Definition: xiroot.cxx:156
sal_Int32 nEndPos
void SetCol(SCCOL nColP)
Definition: address.hxx:279
const XclFontData & GetFontData() const
Returns read-only access to font data.
Definition: xistyle.hxx:87
ScHeaderEditEngine & GetHFEditEngine() const
Returns the edit engine for import/export of headers/footers.
Definition: xlroot.cxx:373
const sal_Unicode EXC_URLSTART_SELFENCODED
Reference to own workbook.
Definition: xlconst.hxx:91
double mfValue
Cached value is a string.
Definition: xihelper.hxx:327
SCSIZE mnScRows
Number of cached columns.
Definition: xihelper.hxx:348
XclFontItemType
Enumerates different types of Which-IDs for font items.
Definition: xlstyle.hxx:388
void SetTab(SCTAB nTabP)
Definition: address.hxx:283
sal_Int32 nEndPara
ESelection maSel
Edit engine text object.
Definition: xihelper.hxx:194
void SetTextCurrentDefaults(const EditTextObject &rTextObject)
SetText and apply defaults already set.
Definition: editutil.cxx:559
ESelection & GetCurrSel()
Returns the current selection.
Definition: xihelper.hxx:206
ScTokenArrayPtr mxTokArr
Cached value is a double.
Definition: xihelper.hxx:328
bool ConvertAddress(ScAddress &rScPos, const XclAddress &rXclPos, SCTAB nScTab, bool bWarn)
Converts the passed Excel cell address to a Calc cell address.
Definition: xihelper.cxx:77
bool mbColTrunc
Maximum row index.
Definition: xladdress.hxx:164
void UpdateCurrMaxLineHeight()
Updates the current maximum line height, using the current font size.
Definition: xihelper.cxx:505
double ReadDouble()
Definition: xistream.cxx:702
OUStringBuffer maCurrText
Edit engine text objects for all portions.
Definition: xihelper.hxx:242
const sal_Unicode EXC_URL_DOSDRIVE
Reference to own workbook (BIFF5/BIFF7).
Definition: xlconst.hxx:94
A 2D cell range address list with Excel column and row indexes.
Definition: xladdress.hxx:101
std::unique_ptr< EditTextObject > CreateTextObject()
XclImpHFPortion meCurrObj
Font data of current text.
Definition: xihelper.hxx:244
const sal_uInt8 EXC_CACHEDVAL_BOOL
Definition: xlconst.hxx:118
bool CheckAddress(const XclAddress &rXclPos, bool bWarn)
Checks if the passed Excel cell address is valid.
Definition: xihelper.cxx:62
void SetRightArea(const EditTextObject &rNew)
Definition: attrib.cxx:482
const sal_Unicode EXC_URL_SUBDIR
Root directory of current drive.
Definition: xlconst.hxx:96
std::vector< XclImpHFPortionInfo > maInfos
The header/footer edit engine.
Definition: xihelper.hxx:241
sal_uInt16 mnCol
Definition: xladdress.hxx:32
A 2D cell address struct with Excel column and row indexes.
Definition: xladdress.hxx:30
XclImpCachedMatrix(XclImpStream &rStrm)
Definition: xihelper.cxx:816
sal_uInt8 mnBoolErr
Cached value is a formula or error code or Boolean.
Definition: xihelper.hxx:329
const sal_uInt8 EXC_FONTUNDERL_SINGLE
Definition: xlstyle.hxx:120
sal_uInt16 ReaduInt16()
Definition: xistream.cxx:648
const sal_uInt8 EXC_CACHEDVAL_EMPTY
Definition: xlconst.hxx:115
FormulaError
ScAddress CreateValidAddress(const XclAddress &rXclPos, SCTAB nScTab, bool bWarn)
Returns a valid cell address by moving it into allowed dimensions.
Definition: xihelper.cxx:86
std::unique_ptr< ScTokenArray > GetBoolErr(XclBoolError)
Definition: excform.cxx:1663
const sal_uInt8 EXC_CACHEDVAL_DOUBLE
Definition: xlconst.hxx:116
const sal_uInt16 EXC_FONTESC_SUPER
Definition: xlstyle.hxx:127
const XclImpRoot & GetRoot() const
Returns the filter root data.
Definition: xistream.hxx:294
std::size_t GetRecLeft()
Returns remaining data size of the whole record without record headers.
Definition: xistream.cxx:581
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
OUString ReadUniString(sal_uInt16 nChars, sal_uInt8 nFlags)
Reads ext.
Definition: xistream.cxx:886
const sal_Unicode EXC_URL_RAW
Parent directory.
Definition: xlconst.hxx:98
ScEditEngineDefaulter & GetEditEngine() const
Returns the edit engine for import/export of rich strings etc.
Definition: xlroot.cxx:358
const OUString & GetText() const
Returns the pure text data of the string.
Definition: xistring.hxx:54
XclImpHFPortionInfo::EditTextObjectRef & GetCurrObj()
Returns the current edit engine text object.
Definition: xihelper.hxx:204
const sal_uInt8 EXC_CACHEDVAL_STRING
Definition: xlconst.hxx:117
void Ignore(std::size_t nBytes)
Seeks forward inside the current record.
Definition: xistream.cxx:795
XclImpCachedValue(const XclImpCachedValue &)=delete
delete copy constructor
sal_uInt8 ReaduInt8()
Definition: xistream.cxx:616
XclImpHFPortionInfo & GetCurrInfo()
Returns the current edit engine text object.
Definition: xihelper.hxx:202
void setStringCell(const ScAddress &rPos, const OUString &rStr)
XclImpFontBuffer & GetFontBuffer() const
Returns the font buffer.
Definition: xiroot.cxx:146
XclImpHFPortion
Enumerates the supported header/footer portions.
Definition: xihelper.hxx:187
void FillToItemSet(SfxItemSet &rItemSet, sal_uInt16 nWhichId) const
Creates a ScPageHFItem and inserts it into the passed item set.
Definition: xihelper.cxx:473
void QuickSetAttribs(const SfxItemSet &rSet, const ESelection &rSel)
Stores the data of all fonts occurred in an Excel file.
Definition: xistyle.hxx:153
sal_uInt16 GetFontIndex(sal_uInt16 nXFIndex) const
Returns the index to the Excel font used in the specified XF record.
Definition: xistyle.cxx:1585
bool mbRowTrunc
Flag for "columns truncated" warning box.
Definition: xladdress.hxx:165
const sal_uInt8 EXC_FONTUNDERL_NONE
Definition: xlstyle.hxx:119
XclBiff GetBiff() const
Returns the current BIFF version of the importer/exporter.
Definition: xlroot.hxx:140
const char * pChar
Base class for import/export address converters.
Definition: xladdress.hxx:139
void InsertField(const SvxFieldItem &rFieldItem)
Inserts the passed text field and adjusts the current selection object.
Definition: xihelper.cxx:547
bool ConvertRange(ScRange &rScRange, const XclRange &rXclRange, SCTAB nScTab1, SCTAB nScTab2, bool bWarn)
Converts the passed Excel cell range to a Calc cell range.
Definition: xihelper.cxx:101
void TraceInvalidAddress(const ScAddress &rPos, const ScAddress &rMaxPos)
Definition: xltracer.cxx:49
const sal_Unicode EXC_URL_DRIVEROOT
DOS drive letter or UNC server name.
Definition: xlconst.hxx:95
#define SAL_WARN(area, stream)
const OUString & GetBasePath() const
Returns the base path of the imported/exported file.
Definition: xlroot.hxx:172
constexpr sal_uInt16 EE_FEATURE_FIELD(EE_FEATURE_NOTCONV+1)
XclImpAddressConverter(const XclImpRoot &rRoot)
Definition: xihelper.cxx:55
void QuickInsertText(const OUString &rText, const ESelection &rSel)
sal_Int32 GetTotalHeight() const
Returns the total height of the converted header or footer in twips.
Definition: xihelper.cxx:485
XclImpValueList maValueList
Definition: xihelper.hxx:346
void CreateCurrObject()
Creates the edit engine text object of current portion from edit engine.
Definition: xihelper.cxx:565
This class is used to import record oriented streams.
Definition: xistream.hxx:278
sal_uInt16 mnFontIdx
First character this format applies to.
Definition: xlstring.hxx:67
XclImpHFConverter(const XclImpHFConverter &)=delete
delete copy constructor
sal_uInt16 mnChar
Definition: xlstring.hxx:66
const sal_uInt8 EXC_FONTUNDERL_DOUBLE
Definition: xlstyle.hxx:121
Access to global data from other classes.
Definition: xiroot.hxx:126
FormulaError GetScError() const
Returns the cached Calc error code, if this value has Error type, else 0.
Definition: xihelper.cxx:809
This class represents an unformatted or formatted string and provides importing from stream...
Definition: xistring.hxx:31
sal_Int32 mnHeight
Edit engine selection.
Definition: xihelper.hxx:195
aStr
void RemoveAll()
Definition: rangelst.cxx:1108
SC_DLLPUBLIC ScFieldEditEngine & GetEditEngine()
Definition: documen2.cxx:454
void InsertText()
Inserts maCurrText into edit engine and adjusts the current selection object.
Definition: xihelper.cxx:535
A 2D cell range address struct with Excel column and row indexes.
Definition: xladdress.hxx:58
sal_uInt16 nPos
sal_Int16 SCTAB
Definition: types.hxx:23
ScDocument & getDoc()
static void DecodeUrl(OUString &rUrl, OUString &rTabName, bool &rbSameWb, const XclImpRoot &rRoot, const OUString &rEncodedUrl)
Decodes an encoded external document URL with optional sheet name.
Definition: xihelper.cxx:603
sal_Int32 nStartPos