re-enabled user-defined numeric fields for dBase export
[LibreOffice.git] / sc / source / core / data / postit.cxx
blob3c03746db1d2eac33e990c314f8f39222498121b
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include "postit.hxx"
23 #include <rtl/ustrbuf.hxx>
24 #include <unotools/useroptions.hxx>
25 #include <svx/svdpage.hxx>
26 #include <svx/svdocapt.hxx>
27 #include <editeng/outlobj.hxx>
28 #include <editeng/editobj.hxx>
29 #include <basegfx/polygon/b2dpolygon.hxx>
31 #include "scitems.hxx"
32 #include <svx/xlnstit.hxx>
33 #include <svx/xlnstwit.hxx>
34 #include <svx/xlnstcit.hxx>
35 #include <svx/sxcecitm.hxx>
36 #include <svx/xflclit.hxx>
37 #include <svx/sdshitm.hxx>
38 #include <svx/sdsxyitm.hxx>
39 #include <tools/gen.hxx>
41 #include "document.hxx"
42 #include "docpool.hxx"
43 #include "patattr.hxx"
44 #include "formulacell.hxx"
45 #include "drwlayer.hxx"
46 #include "userdat.hxx"
47 #include "detfunc.hxx"
49 #include <utility>
52 // ============================================================================
54 namespace {
56 const long SC_NOTECAPTION_WIDTH = 2900; /// Default width of note caption textbox.
57 const long SC_NOTECAPTION_MAXWIDTH_TEMP = 12000; /// Maximum width of temporary note caption textbox.
58 const long SC_NOTECAPTION_HEIGHT = 1800; /// Default height of note caption textbox.
59 const long SC_NOTECAPTION_CELLDIST = 600; /// Default distance of note captions to border of anchor cell.
60 const long SC_NOTECAPTION_OFFSET_Y = -1500; /// Default Y offset of note captions to top border of anchor cell.
61 const long SC_NOTECAPTION_OFFSET_X = 1500; /// Default X offset of note captions to left border of anchor cell.
62 const long SC_NOTECAPTION_BORDERDIST_TEMP = 100; /// Distance of temporary note captions to visible sheet area.
64 // ============================================================================
66 /** Static helper functions for caption objects. */
67 class ScCaptionUtil
69 public:
70 /** Moves the caption object to the correct layer according to passed visibility. */
71 static void SetCaptionLayer( SdrCaptionObj& rCaption, bool bShown );
72 /** Sets basic caption settings required for note caption objects. */
73 static void SetBasicCaptionSettings( SdrCaptionObj& rCaption, bool bShown );
74 /** Stores the cell position of the note in the user data area of the caption. */
75 static void SetCaptionUserData( SdrCaptionObj& rCaption, const ScAddress& rPos );
76 /** Sets all default formatting attributes to the caption object. */
77 static void SetDefaultItems( SdrCaptionObj& rCaption, ScDocument& rDoc );
78 /** Updates caption item set according to the passed item set while removing shadow items. */
79 static void SetCaptionItems( SdrCaptionObj& rCaption, const SfxItemSet& rItemSet );
82 // ----------------------------------------------------------------------------
84 void ScCaptionUtil::SetCaptionLayer( SdrCaptionObj& rCaption, bool bShown )
86 SdrLayerID nLayer = bShown ? SC_LAYER_INTERN : SC_LAYER_HIDDEN;
87 if( nLayer != rCaption.GetLayer() )
88 rCaption.SetLayer( nLayer );
91 void ScCaptionUtil::SetBasicCaptionSettings( SdrCaptionObj& rCaption, bool bShown )
93 SetCaptionLayer( rCaption, bShown );
94 rCaption.SetFixedTail();
95 rCaption.SetSpecialTextBoxShadow();
98 void ScCaptionUtil::SetCaptionUserData( SdrCaptionObj& rCaption, const ScAddress& rPos )
100 // pass true to ScDrawLayer::GetObjData() to create the object data entry
101 ScDrawObjData* pObjData = ScDrawLayer::GetObjData( &rCaption, true );
102 OSL_ENSURE( pObjData, "ScCaptionUtil::SetCaptionUserData - missing drawing object user data" );
103 pObjData->maStart = rPos;
104 pObjData->meType = ScDrawObjData::CellNote;
107 void ScCaptionUtil::SetDefaultItems( SdrCaptionObj& rCaption, ScDocument& rDoc )
109 SfxItemSet aItemSet = rCaption.GetMergedItemSet();
111 // caption tail arrow
112 ::basegfx::B2DPolygon aTriangle;
113 aTriangle.append( ::basegfx::B2DPoint( 10.0, 0.0 ) );
114 aTriangle.append( ::basegfx::B2DPoint( 0.0, 30.0 ) );
115 aTriangle.append( ::basegfx::B2DPoint( 20.0, 30.0 ) );
116 aTriangle.setClosed( true );
117 /* Line ends are now created with an empty name. The
118 checkForUniqueItem() method then finds a unique name for the item's
119 value. */
120 aItemSet.Put( XLineStartItem( String::EmptyString(), ::basegfx::B2DPolyPolygon( aTriangle ) ) );
121 aItemSet.Put( XLineStartWidthItem( 200 ) );
122 aItemSet.Put( XLineStartCenterItem( false ) );
123 aItemSet.Put( XFillStyleItem( XFILL_SOLID ) );
124 aItemSet.Put( XFillColorItem( String::EmptyString(), ScDetectiveFunc::GetCommentColor() ) );
125 aItemSet.Put( SdrCaptionEscDirItem( SDRCAPT_ESCBESTFIT ) );
127 // shadow
128 /* SdrShadowItem has sal_False, instead the shadow is set for the
129 rectangle only with SetSpecialTextBoxShadow() when the object is
130 created (item must be set to adjust objects from older files). */
131 aItemSet.Put( SdrShadowItem( false ) );
132 aItemSet.Put( SdrShadowXDistItem( 100 ) );
133 aItemSet.Put( SdrShadowYDistItem( 100 ) );
135 // text attributes
136 aItemSet.Put( SdrTextLeftDistItem( 100 ) );
137 aItemSet.Put( SdrTextRightDistItem( 100 ) );
138 aItemSet.Put( SdrTextUpperDistItem( 100 ) );
139 aItemSet.Put( SdrTextLowerDistItem( 100 ) );
140 aItemSet.Put( SdrTextAutoGrowWidthItem( false ) );
141 aItemSet.Put( SdrTextAutoGrowHeightItem( true ) );
142 // use the default cell style to be able to modify the caption font
143 const ScPatternAttr& rDefPattern = static_cast< const ScPatternAttr& >( rDoc.GetPool()->GetDefaultItem( ATTR_PATTERN ) );
144 rDefPattern.FillEditItemSet( &aItemSet );
146 rCaption.SetMergedItemSet( aItemSet );
149 void ScCaptionUtil::SetCaptionItems( SdrCaptionObj& rCaption, const SfxItemSet& rItemSet )
151 // copy all items
152 rCaption.SetMergedItemSet( rItemSet );
153 // reset shadow items
154 rCaption.SetMergedItem( SdrShadowItem( false ) );
155 rCaption.SetMergedItem( SdrShadowXDistItem( 100 ) );
156 rCaption.SetMergedItem( SdrShadowYDistItem( 100 ) );
157 rCaption.SetSpecialTextBoxShadow();
160 // ============================================================================
162 /** Helper for creation and manipulation of caption drawing objects independent
163 from cell annotations. */
164 class ScCaptionCreator
166 public:
167 /** Create a new caption. The caption will not be inserted into the document. */
168 explicit ScCaptionCreator( ScDocument& rDoc, const ScAddress& rPos, bool bShown, bool bTailFront );
169 /** Manipulate an existing caption. */
170 explicit ScCaptionCreator( ScDocument& rDoc, const ScAddress& rPos, SdrCaptionObj& rCaption );
172 /** Returns the drawing layer page of the sheet contained in maPos. */
173 SdrPage* GetDrawPage();
174 /** Returns the caption drawing obejct. */
175 inline SdrCaptionObj* GetCaption() { return mpCaption; }
177 /** Moves the caption inside the passed rectangle. Uses page area if 0 is passed. */
178 void FitCaptionToRect( const Rectangle* pVisRect = 0 );
179 /** Places the caption inside the passed rectangle, tries to keep the cell rectangle uncovered. Uses page area if 0 is passed. */
180 void AutoPlaceCaption( const Rectangle* pVisRect = 0 );
181 /** Updates caption tail and textbox according to current cell position. Uses page area if 0 is passed. */
182 void UpdateCaptionPos( const Rectangle* pVisRect = 0 );
184 protected:
185 /** Helper constructor for derived classes. */
186 explicit ScCaptionCreator( ScDocument& rDoc, const ScAddress& rPos );
188 /** Calculates the caption tail position according to current cell position. */
189 Point CalcTailPos( bool bTailFront );
190 /** Implements creation of the caption object. The caption will not be inserted into the document. */
191 void CreateCaption( bool bShown, bool bTailFront );
193 private:
194 /** Initializes all members. */
195 void Initialize();
196 /** Returns the passed rectangle if existing, page rectangle otherwise. */
197 inline const Rectangle& GetVisRect( const Rectangle* pVisRect ) const { return pVisRect ? *pVisRect : maPageRect; }
199 private:
200 ScDocument& mrDoc;
201 ScAddress maPos;
202 SdrCaptionObj* mpCaption;
203 Rectangle maPageRect;
204 Rectangle maCellRect;
205 bool mbNegPage;
208 // ----------------------------------------------------------------------------
210 ScCaptionCreator::ScCaptionCreator( ScDocument& rDoc, const ScAddress& rPos, bool bShown, bool bTailFront ) :
211 mrDoc( rDoc ),
212 maPos( rPos ),
213 mpCaption( 0 )
215 Initialize();
216 CreateCaption( bShown, bTailFront );
219 ScCaptionCreator::ScCaptionCreator( ScDocument& rDoc, const ScAddress& rPos, SdrCaptionObj& rCaption ) :
220 mrDoc( rDoc ),
221 maPos( rPos ),
222 mpCaption( &rCaption )
224 Initialize();
227 ScCaptionCreator::ScCaptionCreator( ScDocument& rDoc, const ScAddress& rPos ) :
228 mrDoc( rDoc ),
229 maPos( rPos ),
230 mpCaption( 0 )
232 Initialize();
235 SdrPage* ScCaptionCreator::GetDrawPage()
237 ScDrawLayer* pDrawLayer = mrDoc.GetDrawLayer();
238 return pDrawLayer ? pDrawLayer->GetPage( static_cast< sal_uInt16 >( maPos.Tab() ) ) : 0;
241 void ScCaptionCreator::FitCaptionToRect( const Rectangle* pVisRect )
243 const Rectangle& rVisRect = GetVisRect( pVisRect );
245 // tail position
246 Point aTailPos = mpCaption->GetTailPos();
247 aTailPos.X() = ::std::max( ::std::min( aTailPos.X(), rVisRect.Right() ), rVisRect.Left() );
248 aTailPos.Y() = ::std::max( ::std::min( aTailPos.Y(), rVisRect.Bottom() ), rVisRect.Top() );
249 mpCaption->SetTailPos( aTailPos );
251 // caption rectangle
252 Rectangle aCaptRect = mpCaption->GetLogicRect();
253 Point aCaptPos = aCaptRect.TopLeft();
254 // move textbox inside right border of visible area
255 aCaptPos.X() = ::std::min< long >( aCaptPos.X(), rVisRect.Right() - aCaptRect.GetWidth() );
256 // move textbox inside left border of visible area (this may move it outside on right side again)
257 aCaptPos.X() = ::std::max< long >( aCaptPos.X(), rVisRect.Left() );
258 // move textbox inside bottom border of visible area
259 aCaptPos.Y() = ::std::min< long >( aCaptPos.Y(), rVisRect.Bottom() - aCaptRect.GetHeight() );
260 // move textbox inside top border of visible area (this may move it outside on bottom side again)
261 aCaptPos.Y() = ::std::max< long >( aCaptPos.Y(), rVisRect.Top() );
262 // update caption
263 aCaptRect.SetPos( aCaptPos );
264 mpCaption->SetLogicRect( aCaptRect );
267 void ScCaptionCreator::AutoPlaceCaption( const Rectangle* pVisRect )
269 const Rectangle& rVisRect = GetVisRect( pVisRect );
271 // caption rectangle
272 Rectangle aCaptRect = mpCaption->GetLogicRect();
273 long nWidth = aCaptRect.GetWidth();
274 long nHeight = aCaptRect.GetHeight();
276 // n***Space contains available space between border of visible area and cell
277 long nLeftSpace = maCellRect.Left() - rVisRect.Left() + 1;
278 long nRightSpace = rVisRect.Right() - maCellRect.Right() + 1;
279 long nTopSpace = maCellRect.Top() - rVisRect.Top() + 1;
280 long nBottomSpace = rVisRect.Bottom() - maCellRect.Bottom() + 1;
282 // nNeeded*** contains textbox dimensions plus needed distances to cell or border of visible area
283 long nNeededSpaceX = nWidth + SC_NOTECAPTION_CELLDIST;
284 long nNeededSpaceY = nHeight + SC_NOTECAPTION_CELLDIST;
286 // bFitsWidth*** == true means width of textbox fits into horizontal free space of visible area
287 bool bFitsWidthLeft = nNeededSpaceX <= nLeftSpace; // text box width fits into the width left of cell
288 bool bFitsWidthRight = nNeededSpaceX <= nRightSpace; // text box width fits into the width right of cell
289 bool bFitsWidth = nWidth <= rVisRect.GetWidth(); // text box width fits into width of visible area
291 // bFitsHeight*** == true means height of textbox fits into vertical free space of visible area
292 bool bFitsHeightTop = nNeededSpaceY <= nTopSpace; // text box height fits into the height above cell
293 bool bFitsHeightBottom = nNeededSpaceY <= nBottomSpace; // text box height fits into the height below cell
294 bool bFitsHeight = nHeight <= rVisRect.GetHeight(); // text box height fits into height of visible area
296 // bFits*** == true means the textbox fits completely into free space of visible area
297 bool bFitsLeft = bFitsWidthLeft && bFitsHeight;
298 bool bFitsRight = bFitsWidthRight && bFitsHeight;
299 bool bFitsTop = bFitsWidth && bFitsHeightTop;
300 bool bFitsBottom = bFitsWidth && bFitsHeightBottom;
302 Point aCaptPos;
303 // use left/right placement if possible, or if top/bottom placement not possible
304 if( bFitsLeft || bFitsRight || (!bFitsTop && !bFitsBottom) )
306 // prefer left in RTL sheet and right in LTR sheets
307 bool bPreferLeft = bFitsLeft && (mbNegPage || !bFitsRight);
308 bool bPreferRight = bFitsRight && (!mbNegPage || !bFitsLeft);
309 // move to left, if left is preferred, or if neither left nor right fit and there is more space to the left
310 if( bPreferLeft || (!bPreferRight && (nLeftSpace > nRightSpace)) )
311 aCaptPos.X() = maCellRect.Left() - SC_NOTECAPTION_CELLDIST - nWidth;
312 else // to right
313 aCaptPos.X() = maCellRect.Right() + SC_NOTECAPTION_CELLDIST;
314 // Y position according to top cell border
315 aCaptPos.Y() = maCellRect.Top() + SC_NOTECAPTION_OFFSET_Y;
317 else // top or bottom placement
319 // X position
320 aCaptPos.X() = maCellRect.Left() + SC_NOTECAPTION_OFFSET_X;
321 // top placement, if possible
322 if( bFitsTop )
323 aCaptPos.Y() = maCellRect.Top() - SC_NOTECAPTION_CELLDIST - nHeight;
324 else // bottom placement
325 aCaptPos.Y() = maCellRect.Bottom() + SC_NOTECAPTION_CELLDIST;
328 // update textbox position in note caption object
329 aCaptRect.SetPos( aCaptPos );
330 mpCaption->SetLogicRect( aCaptRect );
331 FitCaptionToRect( pVisRect );
334 void ScCaptionCreator::UpdateCaptionPos( const Rectangle* pVisRect )
336 ScDrawLayer* pDrawLayer = mrDoc.GetDrawLayer();
338 // update caption position
339 const Point& rOldTailPos = mpCaption->GetTailPos();
340 Point aTailPos = CalcTailPos( false );
341 if( rOldTailPos != aTailPos )
343 // create drawing undo action
344 if( pDrawLayer && pDrawLayer->IsRecording() )
345 pDrawLayer->AddCalcUndo( pDrawLayer->GetSdrUndoFactory().CreateUndoGeoObject( *mpCaption ) );
346 // calculate new caption rectangle (#i98141# handle LTR<->RTL switch correctly)
347 Rectangle aCaptRect = mpCaption->GetLogicRect();
348 long nDiffX = (rOldTailPos.X() >= 0) ? (aCaptRect.Left() - rOldTailPos.X()) : (rOldTailPos.X() - aCaptRect.Right());
349 if( mbNegPage ) nDiffX = -nDiffX - aCaptRect.GetWidth();
350 long nDiffY = aCaptRect.Top() - rOldTailPos.Y();
351 aCaptRect.SetPos( aTailPos + Point( nDiffX, nDiffY ) );
352 // set new tail position and caption rectangle
353 mpCaption->SetTailPos( aTailPos );
354 mpCaption->SetLogicRect( aCaptRect );
355 // fit caption into draw page
356 FitCaptionToRect( pVisRect );
359 // update cell position in caption user data
360 ScDrawObjData* pCaptData = ScDrawLayer::GetNoteCaptionData( mpCaption, maPos.Tab() );
361 if( pCaptData && (maPos != pCaptData->maStart) )
363 // create drawing undo action
364 if( pDrawLayer && pDrawLayer->IsRecording() )
365 pDrawLayer->AddCalcUndo( new ScUndoObjData( mpCaption, pCaptData->maStart, pCaptData->maEnd, maPos, pCaptData->maEnd ) );
366 // set new position
367 pCaptData->maStart = maPos;
371 Point ScCaptionCreator::CalcTailPos( bool bTailFront )
373 // tail position
374 bool bTailLeft = bTailFront != mbNegPage;
375 Point aTailPos = bTailLeft ? maCellRect.TopLeft() : maCellRect.TopRight();
376 // move caption point 1/10 mm inside cell
377 if( bTailLeft ) aTailPos.X() += 10; else aTailPos.X() -= 10;
378 aTailPos.Y() += 10;
379 return aTailPos;
382 void ScCaptionCreator::CreateCaption( bool bShown, bool bTailFront )
384 // create the caption drawing object
385 Rectangle aTextRect( Point( 0 , 0 ), Size( SC_NOTECAPTION_WIDTH, SC_NOTECAPTION_HEIGHT ) );
386 Point aTailPos = CalcTailPos( bTailFront );
387 mpCaption = new SdrCaptionObj( aTextRect, aTailPos );
388 // basic caption settings
389 ScCaptionUtil::SetBasicCaptionSettings( *mpCaption, bShown );
392 void ScCaptionCreator::Initialize()
394 maCellRect = ScDrawLayer::GetCellRect( mrDoc, maPos, true );
395 mbNegPage = mrDoc.IsNegativePage( maPos.Tab() );
396 if( SdrPage* pDrawPage = GetDrawPage() )
398 maPageRect = Rectangle( Point( 0, 0 ), pDrawPage->GetSize() );
399 /* #i98141# SdrPage::GetSize() returns negative width in RTL mode.
400 The call to Rectangle::Adjust() orders left/right coordinate
401 accordingly. */
402 maPageRect.Justify();
406 // ============================================================================
408 /** Helper for creation of permanent caption drawing objects for cell notes. */
409 class ScNoteCaptionCreator : public ScCaptionCreator
411 public:
412 /** Create a new caption object and inserts it into the document. */
413 explicit ScNoteCaptionCreator( ScDocument& rDoc, const ScAddress& rPos, ScNoteData& rNoteData );
414 /** Manipulate an existing caption. */
415 explicit ScNoteCaptionCreator( ScDocument& rDoc, const ScAddress& rPos, SdrCaptionObj& rCaption, bool bShown );
418 // ----------------------------------------------------------------------------
420 ScNoteCaptionCreator::ScNoteCaptionCreator( ScDocument& rDoc, const ScAddress& rPos, ScNoteData& rNoteData ) :
421 ScCaptionCreator( rDoc, rPos ) // use helper c'tor that does not create the caption yet
423 SdrPage* pDrawPage = GetDrawPage();
424 OSL_ENSURE( pDrawPage, "ScNoteCaptionCreator::ScNoteCaptionCreator - no drawing page" );
425 if( pDrawPage )
427 // create the caption drawing object
428 CreateCaption( rNoteData.mbShown, false );
429 rNoteData.mpCaption = GetCaption();
430 OSL_ENSURE( rNoteData.mpCaption, "ScNoteCaptionCreator::ScNoteCaptionCreator - missing caption object" );
431 if( rNoteData.mpCaption )
433 // store note position in user data of caption object
434 ScCaptionUtil::SetCaptionUserData( *rNoteData.mpCaption, rPos );
435 // insert object into draw page
436 pDrawPage->InsertObject( rNoteData.mpCaption );
441 ScNoteCaptionCreator::ScNoteCaptionCreator( ScDocument& rDoc, const ScAddress& rPos, SdrCaptionObj& rCaption, bool bShown ) :
442 ScCaptionCreator( rDoc, rPos, rCaption )
444 SdrPage* pDrawPage = GetDrawPage();
445 OSL_ENSURE( pDrawPage, "ScNoteCaptionCreator::ScNoteCaptionCreator - no drawing page" );
446 OSL_ENSURE( rCaption.GetPage() == pDrawPage, "ScNoteCaptionCreator::ScNoteCaptionCreator - wrong drawing page in caption" );
447 if( pDrawPage && (rCaption.GetPage() == pDrawPage) )
449 // store note position in user data of caption object
450 ScCaptionUtil::SetCaptionUserData( rCaption, rPos );
451 // basic caption settings
452 ScCaptionUtil::SetBasicCaptionSettings( rCaption, bShown );
453 // set correct tail position
454 rCaption.SetTailPos( CalcTailPos( false ) );
458 } // namespace
460 // ============================================================================
462 struct ScCaptionInitData
464 typedef ::std::auto_ptr< SfxItemSet > SfxItemSetPtr;
465 typedef ::std::auto_ptr< OutlinerParaObject > OutlinerParaObjPtr;
467 SfxItemSetPtr mxItemSet; /// Caption object formatting.
468 OutlinerParaObjPtr mxOutlinerObj; /// Text object with all text portion formatting.
469 OUString maSimpleText; /// Simple text without formatting.
470 Point maCaptionOffset; /// Caption position relative to cell corner.
471 Size maCaptionSize; /// Size of the caption object.
472 bool mbDefaultPosSize; /// True = use default position and size for caption.
474 explicit ScCaptionInitData();
477 // ----------------------------------------------------------------------------
479 ScCaptionInitData::ScCaptionInitData() :
480 mbDefaultPosSize( true )
484 // ============================================================================
486 ScNoteData::ScNoteData( bool bShown ) :
487 mpCaption( 0 ),
488 mbShown( bShown )
492 ScNoteData::~ScNoteData()
496 // ============================================================================
498 ScPostIt::ScPostIt( ScDocument& rDoc, const ScAddress& rPos, bool bShown ) :
499 mrDoc( rDoc ),
500 maNoteData( bShown )
502 AutoStamp();
503 CreateCaption( rPos );
506 ScPostIt::ScPostIt( ScDocument& rDoc, const ScAddress& rPos, const ScPostIt& rNote ) :
507 mrDoc( rDoc ),
508 maNoteData( rNote.maNoteData )
510 maNoteData.mpCaption = 0;
511 CreateCaption( rPos, rNote.maNoteData.mpCaption );
514 ScPostIt::ScPostIt( ScDocument& rDoc, const ScAddress& rPos, const ScNoteData& rNoteData, bool bAlwaysCreateCaption ) :
515 mrDoc( rDoc ),
516 maNoteData( rNoteData )
518 if( bAlwaysCreateCaption || maNoteData.mbShown )
519 CreateCaptionFromInitData( rPos );
522 ScPostIt::~ScPostIt()
524 RemoveCaption();
527 ScPostIt* ScPostIt::Clone( const ScAddress& rOwnPos, ScDocument& rDestDoc, const ScAddress& rDestPos, bool bCloneCaption ) const
529 CreateCaptionFromInitData( rOwnPos );
530 return bCloneCaption ? new ScPostIt( rDestDoc, rDestPos, *this ) : new ScPostIt( rDestDoc, rDestPos, maNoteData, false );
533 void ScPostIt::AutoStamp()
535 maNoteData.maDate = ScGlobal::pLocaleData->getDate( Date( Date::SYSTEM ) );
536 maNoteData.maAuthor = SvtUserOptions().GetID();
539 const OutlinerParaObject* ScPostIt::GetOutlinerObject() const
541 if( maNoteData.mpCaption )
542 return maNoteData.mpCaption->GetOutlinerParaObject();
543 if( maNoteData.mxInitData.get() )
544 return maNoteData.mxInitData->mxOutlinerObj.get();
545 return 0;
548 const EditTextObject* ScPostIt::GetEditTextObject() const
550 const OutlinerParaObject* pOPO = GetOutlinerObject();
551 return pOPO ? &pOPO->GetTextObject() : 0;
554 OUString ScPostIt::GetText() const
556 if( const EditTextObject* pEditObj = GetEditTextObject() )
558 OUStringBuffer aBuffer;
559 for( sal_Int32 nPara = 0, nParaCount = pEditObj->GetParagraphCount(); nPara < nParaCount; ++nPara )
561 if( nPara > 0 )
562 aBuffer.append( sal_Unicode( '\n' ) );
563 aBuffer.append( pEditObj->GetText( nPara ) );
565 return aBuffer.makeStringAndClear();
567 if( maNoteData.mxInitData.get() )
568 return maNoteData.mxInitData->maSimpleText;
569 return OUString();
572 void ScPostIt::SetText( const ScAddress& rPos, const OUString& rText )
574 CreateCaptionFromInitData( rPos );
575 if( maNoteData.mpCaption )
576 maNoteData.mpCaption->SetText( rText );
579 SdrCaptionObj* ScPostIt::GetOrCreateCaption( const ScAddress& rPos ) const
581 CreateCaptionFromInitData( rPos );
582 return maNoteData.mpCaption;
585 void ScPostIt::ForgetCaption()
587 /* This function is used in undo actions to give up the responsibility for
588 the caption object which is handled by separate drawing undo actions. */
589 maNoteData.mpCaption = 0;
590 maNoteData.mxInitData.reset();
593 void ScPostIt::ShowCaption( const ScAddress& rPos, bool bShow )
595 CreateCaptionFromInitData( rPos );
596 // no separate drawing undo needed, handled completely inside ScUndoShowHideNote
597 maNoteData.mbShown = bShow;
598 if( maNoteData.mpCaption )
599 ScCaptionUtil::SetCaptionLayer( *maNoteData.mpCaption, bShow );
602 void ScPostIt::ShowCaptionTemp( const ScAddress& rPos, bool bShow )
604 CreateCaptionFromInitData( rPos );
605 if( maNoteData.mpCaption )
606 ScCaptionUtil::SetCaptionLayer( *maNoteData.mpCaption, maNoteData.mbShown || bShow );
609 void ScPostIt::UpdateCaptionPos( const ScAddress& rPos )
611 CreateCaptionFromInitData( rPos );
612 if( maNoteData.mpCaption )
614 ScCaptionCreator aCreator( mrDoc, rPos, *maNoteData.mpCaption );
615 aCreator.UpdateCaptionPos();
619 // private --------------------------------------------------------------------
621 void ScPostIt::CreateCaptionFromInitData( const ScAddress& rPos ) const
623 OSL_ENSURE( maNoteData.mpCaption || maNoteData.mxInitData.get(), "ScPostIt::CreateCaptionFromInitData - need caption object or initial caption data" );
624 if( maNoteData.mxInitData.get() )
626 /* This function is called from ScPostIt::Clone() when copying cells
627 to the clipboard/undo document, and when copying cells from the
628 clipboard/undo document. The former should always be called first,
629 so if called in an clipboard/undo document, the caption should have
630 been created already. */
631 OSL_ENSURE( !mrDoc.IsUndo() && !mrDoc.IsClipboard(), "ScPostIt::CreateCaptionFromInitData - note caption should not be created in undo/clip documents" );
633 /* #i104915# Never try to create notes in Undo document, leads to
634 crash due to missing document members (e.g. row height array). */
635 if( !maNoteData.mpCaption && !mrDoc.IsUndo() )
637 // ScNoteCaptionCreator c'tor creates the caption and inserts it into the document and maNoteData
638 ScNoteCaptionCreator aCreator( mrDoc, rPos, maNoteData );
639 if( maNoteData.mpCaption )
641 ScCaptionInitData& rInitData = *maNoteData.mxInitData;
643 // transfer ownership of outliner object to caption, or set simple text
644 OSL_ENSURE( rInitData.mxOutlinerObj.get() || !rInitData.maSimpleText.isEmpty(),
645 "ScPostIt::CreateCaptionFromInitData - need either outliner para object or simple text" );
646 if( rInitData.mxOutlinerObj.get() )
647 maNoteData.mpCaption->SetOutlinerParaObject( rInitData.mxOutlinerObj.release() );
648 else
649 maNoteData.mpCaption->SetText( rInitData.maSimpleText );
651 // copy all items or set default items; reset shadow items
652 ScCaptionUtil::SetDefaultItems( *maNoteData.mpCaption, mrDoc );
653 if( rInitData.mxItemSet.get() )
654 ScCaptionUtil::SetCaptionItems( *maNoteData.mpCaption, *rInitData.mxItemSet );
656 // set position and size of the caption object
657 if( rInitData.mbDefaultPosSize )
659 // set other items and fit caption size to text
660 maNoteData.mpCaption->SetMergedItem( SdrTextMinFrameWidthItem( SC_NOTECAPTION_WIDTH ) );
661 maNoteData.mpCaption->SetMergedItem( SdrTextMaxFrameWidthItem( SC_NOTECAPTION_MAXWIDTH_TEMP ) );
662 maNoteData.mpCaption->AdjustTextFrameWidthAndHeight();
663 aCreator.AutoPlaceCaption();
665 else
667 Rectangle aCellRect = ScDrawLayer::GetCellRect( mrDoc, rPos, true );
668 bool bNegPage = mrDoc.IsNegativePage( rPos.Tab() );
669 long nPosX = bNegPage ? (aCellRect.Left() - rInitData.maCaptionOffset.X()) : (aCellRect.Right() + rInitData.maCaptionOffset.X());
670 long nPosY = aCellRect.Top() + rInitData.maCaptionOffset.Y();
671 Rectangle aCaptRect( Point( nPosX, nPosY ), rInitData.maCaptionSize );
672 maNoteData.mpCaption->SetLogicRect( aCaptRect );
673 aCreator.FitCaptionToRect();
677 // forget the initial caption data struct
678 maNoteData.mxInitData.reset();
682 void ScPostIt::CreateCaption( const ScAddress& rPos, const SdrCaptionObj* pCaption )
684 OSL_ENSURE( !maNoteData.mpCaption, "ScPostIt::CreateCaption - unexpected caption object found" );
685 maNoteData.mpCaption = 0;
687 /* #i104915# Never try to create notes in Undo document, leads to
688 crash due to missing document members (e.g. row height array). */
689 OSL_ENSURE( !mrDoc.IsUndo(), "ScPostIt::CreateCaption - note caption should not be created in undo documents" );
690 if( mrDoc.IsUndo() )
691 return;
693 // drawing layer may be missing, if a note is copied into a clipboard document
694 if( mrDoc.IsClipboard() )
695 mrDoc.InitDrawLayer();
697 // ScNoteCaptionCreator c'tor creates the caption and inserts it into the document and maNoteData
698 ScNoteCaptionCreator aCreator( mrDoc, rPos, maNoteData );
699 if( maNoteData.mpCaption )
701 // clone settings of passed caption
702 if( pCaption )
704 // copy edit text object (object must be inserted into page already)
705 if( OutlinerParaObject* pOPO = pCaption->GetOutlinerParaObject() )
706 maNoteData.mpCaption->SetOutlinerParaObject( new OutlinerParaObject( *pOPO ) );
707 // copy formatting items (after text has been copied to apply font formatting)
708 maNoteData.mpCaption->SetMergedItemSetAndBroadcast( pCaption->GetMergedItemSet() );
709 // move textbox position relative to new cell, copy textbox size
710 Rectangle aCaptRect = pCaption->GetLogicRect();
711 Point aDist = maNoteData.mpCaption->GetTailPos() - pCaption->GetTailPos();
712 aCaptRect.Move( aDist.X(), aDist.Y() );
713 maNoteData.mpCaption->SetLogicRect( aCaptRect );
714 aCreator.FitCaptionToRect();
716 else
718 // set default formatting and default position
719 ScCaptionUtil::SetDefaultItems( *maNoteData.mpCaption, mrDoc );
720 aCreator.AutoPlaceCaption();
723 // create undo action
724 if( ScDrawLayer* pDrawLayer = mrDoc.GetDrawLayer() )
725 if( pDrawLayer->IsRecording() )
726 pDrawLayer->AddCalcUndo( pDrawLayer->GetSdrUndoFactory().CreateUndoNewObject( *maNoteData.mpCaption ) );
730 void ScPostIt::RemoveCaption()
733 /* Remove caption object only, if this note is its owner (e.g. notes in
734 undo documents refer to captions in original document, do not remove
735 them from drawing layer here). */
736 ScDrawLayer* pDrawLayer = mrDoc.GetDrawLayer();
737 if( maNoteData.mpCaption && (pDrawLayer == maNoteData.mpCaption->GetModel()) )
739 OSL_ENSURE( pDrawLayer, "ScPostIt::RemoveCaption - object without drawing layer" );
740 SdrPage* pDrawPage = maNoteData.mpCaption->GetPage();
741 OSL_ENSURE( pDrawPage, "ScPostIt::RemoveCaption - object without drawing page" );
742 if( pDrawPage )
744 pDrawPage->RecalcObjOrdNums();
745 // create drawing undo action (before removing the object to have valid draw page in undo action)
746 bool bRecording = ( pDrawLayer && pDrawLayer->IsRecording() );
747 if( bRecording )
748 pDrawLayer->AddCalcUndo( pDrawLayer->GetSdrUndoFactory().CreateUndoDeleteObject( *maNoteData.mpCaption ) );
749 // remove the object from the drawing page, delete if undo is disabled
750 SdrObject* pObj = pDrawPage->RemoveObject( maNoteData.mpCaption->GetOrdNum() );
751 if( !bRecording )
752 SdrObject::Free( pObj );
755 maNoteData.mpCaption = 0;
758 // ============================================================================
760 void ScNoteUtil::UpdateCaptionPositions( ScDocument& rDoc, const ScRange& rRange )
762 // do not use ScCellIterator, it skips filtered and subtotal cells
763 for( ScAddress aPos( rRange.aStart ); aPos.Tab() <= rRange.aEnd.Tab(); aPos.IncTab() )
764 for( aPos.SetCol( rRange.aStart.Col() ); aPos.Col() <= rRange.aEnd.Col(); aPos.IncCol() )
765 for( aPos.SetRow( rRange.aStart.Row() ); aPos.Row() <= rRange.aEnd.Row(); aPos.IncRow() )
766 if( ScPostIt* pNote = rDoc.GetNotes(aPos.Tab())->findByAddress( aPos ) )
767 pNote->UpdateCaptionPos( aPos );
770 SdrCaptionObj* ScNoteUtil::CreateTempCaption(
771 ScDocument& rDoc, const ScAddress& rPos, SdrPage& rDrawPage,
772 const OUString& rUserText, const Rectangle& rVisRect, bool bTailFront )
774 OUStringBuffer aBuffer( rUserText );
775 // add plain text of invisible (!) cell note (no formatting etc.)
776 SdrCaptionObj* pNoteCaption = 0;
777 const ScPostIt* pNote = rDoc.GetNotes(rPos.Tab())->findByAddress( rPos );
778 if( pNote && !pNote->IsCaptionShown() )
780 if( aBuffer.getLength() > 0 )
781 aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( "\n--------\n" ) ).append( pNote->GetText() );
782 pNoteCaption = pNote->GetOrCreateCaption( rPos );
785 // create a caption if any text exists
786 if( !pNoteCaption && (aBuffer.getLength() == 0) )
787 return 0;
789 // prepare visible rectangle (add default distance to all borders)
790 Rectangle aVisRect(
791 rVisRect.Left() + SC_NOTECAPTION_BORDERDIST_TEMP,
792 rVisRect.Top() + SC_NOTECAPTION_BORDERDIST_TEMP,
793 rVisRect.Right() - SC_NOTECAPTION_BORDERDIST_TEMP,
794 rVisRect.Bottom() - SC_NOTECAPTION_BORDERDIST_TEMP );
796 // create the caption object
797 ScCaptionCreator aCreator( rDoc, rPos, true, bTailFront );
798 SdrCaptionObj* pCaption = aCreator.GetCaption();
800 // insert caption into page (needed to set caption text)
801 rDrawPage.InsertObject( pCaption );
803 // clone the edit text object, unless user text is present, then set this text
804 if( pNoteCaption && rUserText.isEmpty() )
806 if( OutlinerParaObject* pOPO = pNoteCaption->GetOutlinerParaObject() )
807 pCaption->SetOutlinerParaObject( new OutlinerParaObject( *pOPO ) );
808 // set formatting (must be done after setting text) and resize the box to fit the text
809 pCaption->SetMergedItemSetAndBroadcast( pNoteCaption->GetMergedItemSet() );
810 Rectangle aCaptRect( pCaption->GetLogicRect().TopLeft(), pNoteCaption->GetLogicRect().GetSize() );
811 pCaption->SetLogicRect( aCaptRect );
813 else
815 // if pNoteCaption is null, then aBuffer contains some text
816 pCaption->SetText( aBuffer.makeStringAndClear() );
817 ScCaptionUtil::SetDefaultItems( *pCaption, rDoc );
818 // adjust caption size to text size
819 long nMaxWidth = ::std::min< long >( aVisRect.GetWidth() * 2 / 3, SC_NOTECAPTION_MAXWIDTH_TEMP );
820 pCaption->SetMergedItem( SdrTextAutoGrowWidthItem( sal_True ) );
821 pCaption->SetMergedItem( SdrTextMinFrameWidthItem( SC_NOTECAPTION_WIDTH ) );
822 pCaption->SetMergedItem( SdrTextMaxFrameWidthItem( nMaxWidth ) );
823 pCaption->SetMergedItem( SdrTextAutoGrowHeightItem( sal_True ) );
824 pCaption->AdjustTextFrameWidthAndHeight();
827 // move caption into visible area
828 aCreator.AutoPlaceCaption( &aVisRect );
829 return pCaption;
832 ScPostIt* ScNoteUtil::CreateNoteFromCaption(
833 ScDocument& rDoc, const ScAddress& rPos, SdrCaptionObj& rCaption, bool bShown )
835 ScNoteData aNoteData( bShown );
836 aNoteData.mpCaption = &rCaption;
837 ScPostIt* pNote = new ScPostIt( rDoc, rPos, aNoteData, false );
838 pNote->AutoStamp();
840 // if pNote still points to the note after TakeNote(), insertion was successful
841 if( rDoc.GetNotes(rPos.Tab())->insert( rPos, pNote ) )
843 // ScNoteCaptionCreator c'tor updates the caption object to be part of a note
844 ScNoteCaptionCreator aCreator( rDoc, rPos, rCaption, bShown );
846 else
847 return NULL;
849 return pNote;
852 ScPostIt* ScNoteUtil::CreateNoteFromObjectData(
853 ScDocument& rDoc, const ScAddress& rPos, SfxItemSet* pItemSet,
854 OutlinerParaObject* pOutlinerObj, const Rectangle& rCaptionRect,
855 bool bShown, bool bAlwaysCreateCaption )
857 OSL_ENSURE( pItemSet && pOutlinerObj, "ScNoteUtil::CreateNoteFromObjectData - item set and outliner object expected" );
858 ScNoteData aNoteData( bShown );
859 aNoteData.mxInitData.reset( new ScCaptionInitData );
860 ScCaptionInitData& rInitData = *aNoteData.mxInitData;
861 rInitData.mxItemSet.reset( pItemSet );
862 rInitData.mxOutlinerObj.reset( pOutlinerObj );
864 // convert absolute caption position to relative position
865 rInitData.mbDefaultPosSize = rCaptionRect.IsEmpty();
866 if( !rInitData.mbDefaultPosSize )
868 Rectangle aCellRect = ScDrawLayer::GetCellRect( rDoc, rPos, true );
869 bool bNegPage = rDoc.IsNegativePage( rPos.Tab() );
870 rInitData.maCaptionOffset.X() = bNegPage ? (aCellRect.Left() - rCaptionRect.Right()) : (rCaptionRect.Left() - aCellRect.Right());
871 rInitData.maCaptionOffset.Y() = rCaptionRect.Top() - aCellRect.Top();
872 rInitData.maCaptionSize = rCaptionRect.GetSize();
875 /* Create the note and insert it into the document. If the note is
876 visible, the caption object will be created automatically. */
877 ScPostIt* pNote = new ScPostIt( rDoc, rPos, aNoteData, bAlwaysCreateCaption );
878 pNote->AutoStamp();
879 if(rDoc.GetNotes(rPos.Tab())->insert( rPos, pNote ))
880 return pNote;
881 else
882 return NULL;
885 ScPostIt* ScNoteUtil::CreateNoteFromString(
886 ScDocument& rDoc, const ScAddress& rPos, const OUString& rNoteText,
887 bool bShown, bool bAlwaysCreateCaption )
889 ScPostIt* pNote = 0;
890 if( !rNoteText.isEmpty() )
892 ScNoteData aNoteData( bShown );
893 aNoteData.mxInitData.reset( new ScCaptionInitData );
894 ScCaptionInitData& rInitData = *aNoteData.mxInitData;
895 rInitData.maSimpleText = rNoteText;
896 rInitData.mbDefaultPosSize = true;
898 /* Create the note and insert it into the document. If the note is
899 visible, the caption object will be created automatically. */
900 pNote = new ScPostIt( rDoc, rPos, aNoteData, bAlwaysCreateCaption );
901 pNote->AutoStamp();
902 //insert takes ownership
903 if(!rDoc.GetNotes(rPos.Tab())->insert( rPos, pNote ))
904 pNote = NULL;
906 return pNote;
909 // ============================================================================
910 // ScNotes
911 // ============================================================================
913 ScNotes::ScNotes(ScDocument* pDoc):
914 mpDoc(pDoc)
919 ScNotes::~ScNotes()
921 clear();
924 ScNotes::iterator ScNotes::begin()
926 return maNoteMap.begin();
929 ScNotes::iterator ScNotes::end()
931 return maNoteMap.end();
934 ScNotes::const_iterator ScNotes::begin() const
936 return maNoteMap.begin();
939 ScNotes::const_iterator ScNotes::end() const
941 return maNoteMap.end();
944 size_t ScNotes::size() const
946 return maNoteMap.size();
949 bool ScNotes::empty() const
951 return maNoteMap.empty();
954 ScPostIt* ScNotes::findByAddress(SCCOL nCol, SCROW nRow)
956 ScNoteMap::iterator itr = maNoteMap.find(std::pair<SCCOL, SCROW>(nCol, nRow));
957 if (itr != maNoteMap.end())
958 return itr->second;
960 return NULL;
963 const ScPostIt* ScNotes::findByAddress(SCCOL nCol, SCROW nRow) const
965 ScNoteMap::const_iterator itr = maNoteMap.find(std::pair<SCCOL, SCROW>(nCol, nRow));
966 if (itr != maNoteMap.end())
967 return itr->second;
969 return NULL;
972 ScPostIt* ScNotes::findByAddress(const ScAddress& rPos)
974 return findByAddress(rPos.Col(), rPos.Row());
977 const ScPostIt* ScNotes::findByAddress(const ScAddress& rPos) const
979 return findByAddress(rPos.Col(), rPos.Row());
982 bool ScNotes::insert(SCCOL nCol, SCROW nRow, ScPostIt* pPostIt)
984 std::pair<iterator, bool> aResult = maNoteMap.insert(std::pair<ScAddress2D, ScPostIt*>(std::pair<SCCOL, SCROW>(nCol, nRow), pPostIt));
985 if (!aResult.second)
986 delete pPostIt;
988 return aResult.second;
991 bool ScNotes::insert(const ScAddress& rPos, ScPostIt* pPostIt)
993 return insert(rPos.Col(), rPos.Row(), pPostIt);
996 void ScNotes::erase(SCCOL nCol, SCROW nRow, bool bForgetCaption)
998 iterator itr = maNoteMap.find(std::pair<SCCOL, SCROW>(nCol, nRow));
999 if (itr != maNoteMap.end())
1001 if (bForgetCaption)
1002 itr->second->ForgetCaption();
1004 delete itr->second;
1005 maNoteMap.erase(itr);
1009 void ScNotes::erase(const ScAddress& rPos)
1011 erase(rPos.Col(), rPos.Row());
1014 ScPostIt* ScNotes::ReleaseNote(SCCOL nCol, SCROW nRow)
1016 ScPostIt* pPostIt = NULL;
1017 iterator itr = maNoteMap.find(std::pair<SCCOL, SCROW>(nCol, nRow));
1018 if (itr!= maNoteMap.end())
1020 pPostIt = itr->second;
1021 maNoteMap.erase(itr);
1023 return pPostIt;
1026 ScPostIt* ScNotes::ReleaseNote(const ScAddress& rPos)
1028 return ReleaseNote(rPos.Col(), rPos.Row());
1031 ScPostIt* ScNotes::GetOrCreateNote(const ScAddress& rPos)
1033 iterator itr = maNoteMap.find(std::pair<SCCOL, SCROW>(rPos.Col(), rPos.Row()));
1034 if (itr != maNoteMap.end())
1035 return itr->second;
1036 else
1038 ScPostIt* pPostIt = new ScPostIt(*mpDoc, rPos, false);
1039 if(!insert(rPos, pPostIt))
1040 assert(false);
1041 return pPostIt;
1045 void ScNotes::clear()
1047 for (iterator itr = maNoteMap.begin(); itr != maNoteMap.end(); ++itr)
1049 delete itr->second;
1051 maNoteMap.clear();
1054 void ScNotes::clone(ScDocument* pDoc, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, bool bCloneNoteCaption, SCTAB nTab, ScNotes& rTarget)
1056 rTarget.clear();
1057 for (ScNotes::iterator itr = maNoteMap.begin(); itr != maNoteMap.end(); ++itr)
1059 SCCOL nCol = itr->first.first;
1060 SCROW nRow = itr->first.second;
1062 if (nCol >= nCol1 && nCol <= nCol2 && nRow >= nRow1 && nRow <= nRow2)
1064 rTarget.insert(nCol, nRow, itr->second->Clone( ScAddress(nCol, nRow, nTab), *pDoc, ScAddress(nCol, nRow, nTab), bCloneNoteCaption));
1069 void ScNotes::CopyFromClip(const ScNotes& rNotes, ScDocument* pDoc, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, SCsCOL nDx, SCsROW nDy, SCTAB nTab, bool bCloneCaption)
1071 for (ScNotes::const_iterator itr = rNotes.begin(); itr != rNotes.end(); ++itr)
1073 SCCOL nCol = itr->first.first;
1074 SCROW nRow = itr->first.second;
1075 if (nCol+nDx >= nCol1 && nCol+nDx <= nCol2 && nRow+nDy >= nRow1 && nRow+nDy <= nRow2)
1077 erase(nCol+nDx, nRow+nDy);
1078 insert(nCol+nDx, nRow+nDy, itr->second->Clone( ScAddress(nCol, nRow, nTab), *pDoc, ScAddress(nCol+nDx, nRow+nDy, nTab), bCloneCaption ));
1083 void ScNotes::erase(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, bool bForgetCaption)
1085 ScNotes::iterator itr = maNoteMap.begin();
1086 while(itr != maNoteMap.end())
1088 SCCOL nCol = itr->first.first;
1089 SCROW nRow = itr->first.second;
1090 ++itr;
1091 if (nCol >= nCol1 && nCol <= nCol2 && nRow >= nRow1 && nRow <= nRow2)
1093 erase(nCol, nRow, bForgetCaption);
1098 void ScNotes::CreateAllNoteCaptions(SCTAB nTab)
1100 for(iterator itr = begin(), itrEnd = end(); itr != itrEnd; ++itr)
1102 itr->second->GetOrCreateCaption(ScAddress(itr->first.first, itr->first.second, nTab));
1106 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */