xref: /AOO41X/main/sc/source/core/data/postit.cxx (revision 577c0052d6abf034578ac9c5775082c46c25eec4)
1b3f79822SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3b3f79822SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4b3f79822SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5b3f79822SAndrew Rist  * distributed with this work for additional information
6b3f79822SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7b3f79822SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8b3f79822SAndrew Rist  * "License"); you may not use this file except in compliance
9b3f79822SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11b3f79822SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13b3f79822SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14b3f79822SAndrew Rist  * software distributed under the License is distributed on an
15b3f79822SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16b3f79822SAndrew Rist  * KIND, either express or implied.  See the License for the
17b3f79822SAndrew Rist  * specific language governing permissions and limitations
18b3f79822SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20b3f79822SAndrew Rist  *************************************************************/
21b3f79822SAndrew Rist 
22b3f79822SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sc.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include "postit.hxx"
28cdf0e10cSrcweir 
29cdf0e10cSrcweir #include <rtl/ustrbuf.hxx>
30cdf0e10cSrcweir #include <unotools/useroptions.hxx>
31cdf0e10cSrcweir #include <svx/svdpage.hxx>
32cdf0e10cSrcweir #include <svx/svdocapt.hxx>
33cdf0e10cSrcweir #include <editeng/outlobj.hxx>
34cdf0e10cSrcweir #include <editeng/editobj.hxx>
35cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygon.hxx>
36cdf0e10cSrcweir 
37cdf0e10cSrcweir #include "scitems.hxx"
38cdf0e10cSrcweir #include <svx/xlnstit.hxx>
39cdf0e10cSrcweir #include <svx/xlnstwit.hxx>
40cdf0e10cSrcweir #include <svx/xlnstcit.hxx>
41cdf0e10cSrcweir #include <svx/sxcecitm.hxx>
42cdf0e10cSrcweir #include <svx/xflclit.hxx>
43cdf0e10cSrcweir #include <svx/sdshitm.hxx>
44cdf0e10cSrcweir #include <svx/sdsxyitm.hxx>
45cdf0e10cSrcweir 
46cdf0e10cSrcweir #include "document.hxx"
47cdf0e10cSrcweir #include "docpool.hxx"
48cdf0e10cSrcweir #include "patattr.hxx"
49cdf0e10cSrcweir #include "cell.hxx"
50cdf0e10cSrcweir #include "drwlayer.hxx"
51cdf0e10cSrcweir #include "userdat.hxx"
52cdf0e10cSrcweir #include "detfunc.hxx"
53cdf0e10cSrcweir 
54cdf0e10cSrcweir using ::rtl::OUString;
55cdf0e10cSrcweir using ::rtl::OUStringBuffer;
56cdf0e10cSrcweir 
57cdf0e10cSrcweir // ============================================================================
58cdf0e10cSrcweir 
59cdf0e10cSrcweir namespace {
60cdf0e10cSrcweir 
61cdf0e10cSrcweir const long SC_NOTECAPTION_WIDTH             =  2900;    /// Default width of note caption textbox.
62cdf0e10cSrcweir const long SC_NOTECAPTION_MAXWIDTH_TEMP     = 12000;    /// Maximum width of temporary note caption textbox.
63cdf0e10cSrcweir const long SC_NOTECAPTION_HEIGHT            =  1800;    /// Default height of note caption textbox.
64cdf0e10cSrcweir const long SC_NOTECAPTION_CELLDIST          =   600;    /// Default distance of note captions to border of anchor cell.
65cdf0e10cSrcweir const long SC_NOTECAPTION_OFFSET_Y          = -1500;    /// Default Y offset of note captions to top border of anchor cell.
66cdf0e10cSrcweir const long SC_NOTECAPTION_OFFSET_X          =  1500;    /// Default X offset of note captions to left border of anchor cell.
67cdf0e10cSrcweir const long SC_NOTECAPTION_BORDERDIST_TEMP   =   100;    /// Distance of temporary note captions to visible sheet area.
68cdf0e10cSrcweir 
69cdf0e10cSrcweir // ============================================================================
70cdf0e10cSrcweir 
71cdf0e10cSrcweir /** Static helper functions for caption objects. */
72cdf0e10cSrcweir class ScCaptionUtil
73cdf0e10cSrcweir {
74cdf0e10cSrcweir public:
75cdf0e10cSrcweir     /** Moves the caption object to the correct layer according to passed visibility. */
76cdf0e10cSrcweir     static void         SetCaptionLayer( SdrCaptionObj& rCaption, bool bShown );
77cdf0e10cSrcweir     /** Sets basic caption settings required for note caption objects. */
78cdf0e10cSrcweir     static void         SetBasicCaptionSettings( SdrCaptionObj& rCaption, bool bShown );
79cdf0e10cSrcweir     /** Stores the cell position of the note in the user data area of the caption. */
80cdf0e10cSrcweir     static void         SetCaptionUserData( SdrCaptionObj& rCaption, const ScAddress& rPos );
81cdf0e10cSrcweir     /** Sets all default formatting attributes to the caption object. */
82cdf0e10cSrcweir     static void         SetDefaultItems( SdrCaptionObj& rCaption, ScDocument& rDoc );
83cdf0e10cSrcweir     /** Updates caption item set according to the passed item set while removing shadow items. */
84cdf0e10cSrcweir     static void         SetCaptionItems( SdrCaptionObj& rCaption, const SfxItemSet& rItemSet );
85cdf0e10cSrcweir };
86cdf0e10cSrcweir 
87cdf0e10cSrcweir // ----------------------------------------------------------------------------
88cdf0e10cSrcweir 
SetCaptionLayer(SdrCaptionObj & rCaption,bool bShown)89cdf0e10cSrcweir void ScCaptionUtil::SetCaptionLayer( SdrCaptionObj& rCaption, bool bShown )
90cdf0e10cSrcweir {
91cdf0e10cSrcweir     SdrLayerID nLayer = bShown ? SC_LAYER_INTERN : SC_LAYER_HIDDEN;
92cdf0e10cSrcweir     if( nLayer != rCaption.GetLayer() )
93cdf0e10cSrcweir         rCaption.SetLayer( nLayer );
94cdf0e10cSrcweir }
95cdf0e10cSrcweir 
SetBasicCaptionSettings(SdrCaptionObj & rCaption,bool bShown)96cdf0e10cSrcweir void ScCaptionUtil::SetBasicCaptionSettings( SdrCaptionObj& rCaption, bool bShown )
97cdf0e10cSrcweir {
98cdf0e10cSrcweir     ScDrawLayer::SetAnchor( &rCaption, SCA_PAGE );
99cdf0e10cSrcweir     SetCaptionLayer( rCaption, bShown );
100cdf0e10cSrcweir     rCaption.SetFixedTail();
101cdf0e10cSrcweir     rCaption.SetSpecialTextBoxShadow();
102cdf0e10cSrcweir }
103cdf0e10cSrcweir 
SetCaptionUserData(SdrCaptionObj & rCaption,const ScAddress & rPos)104cdf0e10cSrcweir void ScCaptionUtil::SetCaptionUserData( SdrCaptionObj& rCaption, const ScAddress& rPos )
105cdf0e10cSrcweir {
106cdf0e10cSrcweir     // pass true to ScDrawLayer::GetObjData() to create the object data entry
107cdf0e10cSrcweir     ScDrawObjData* pObjData = ScDrawLayer::GetObjData( &rCaption, true );
108cdf0e10cSrcweir     OSL_ENSURE( pObjData, "ScCaptionUtil::SetCaptionUserData - missing drawing object user data" );
109cdf0e10cSrcweir     pObjData->maStart = rPos;
110cdf0e10cSrcweir     pObjData->mbNote = true;
111cdf0e10cSrcweir }
112cdf0e10cSrcweir 
SetDefaultItems(SdrCaptionObj & rCaption,ScDocument & rDoc)113cdf0e10cSrcweir void ScCaptionUtil::SetDefaultItems( SdrCaptionObj& rCaption, ScDocument& rDoc )
114cdf0e10cSrcweir {
115cdf0e10cSrcweir     SfxItemSet aItemSet = rCaption.GetMergedItemSet();
116cdf0e10cSrcweir 
117cdf0e10cSrcweir     // caption tail arrow
118cdf0e10cSrcweir     ::basegfx::B2DPolygon aTriangle;
119cdf0e10cSrcweir     aTriangle.append( ::basegfx::B2DPoint( 10.0,  0.0 ) );
120cdf0e10cSrcweir     aTriangle.append( ::basegfx::B2DPoint(  0.0, 30.0 ) );
121cdf0e10cSrcweir     aTriangle.append( ::basegfx::B2DPoint( 20.0, 30.0 ) );
122cdf0e10cSrcweir     aTriangle.setClosed( true );
123cdf0e10cSrcweir     /*  #99319# Line ends are now created with an empty name. The
124cdf0e10cSrcweir         checkForUniqueItem() method then finds a unique name for the item's
125cdf0e10cSrcweir         value. */
126cdf0e10cSrcweir     aItemSet.Put( XLineStartItem( String::EmptyString(), ::basegfx::B2DPolyPolygon( aTriangle ) ) );
127cdf0e10cSrcweir     aItemSet.Put( XLineStartWidthItem( 200 ) );
128cdf0e10cSrcweir     aItemSet.Put( XLineStartCenterItem( sal_False ) );
129cdf0e10cSrcweir     aItemSet.Put( XFillStyleItem( XFILL_SOLID ) );
130cdf0e10cSrcweir     aItemSet.Put( XFillColorItem( String::EmptyString(), ScDetectiveFunc::GetCommentColor() ) );
131cdf0e10cSrcweir     aItemSet.Put( SdrCaptionEscDirItem( SDRCAPT_ESCBESTFIT ) );
132cdf0e10cSrcweir 
133cdf0e10cSrcweir     // shadow
134cdf0e10cSrcweir     /*  SdrShadowItem has sal_False, instead the shadow is set for the
135cdf0e10cSrcweir         rectangle only with SetSpecialTextBoxShadow() when the object is
136cdf0e10cSrcweir         created (item must be set to adjust objects from older files). */
137cdf0e10cSrcweir     aItemSet.Put( SdrShadowItem( sal_False ) );
138cdf0e10cSrcweir     aItemSet.Put( SdrShadowXDistItem( 100 ) );
139cdf0e10cSrcweir     aItemSet.Put( SdrShadowYDistItem( 100 ) );
140cdf0e10cSrcweir 
141cdf0e10cSrcweir     // text attributes
142cdf0e10cSrcweir     aItemSet.Put( SdrTextLeftDistItem( 100 ) );
143cdf0e10cSrcweir     aItemSet.Put( SdrTextRightDistItem( 100 ) );
144cdf0e10cSrcweir     aItemSet.Put( SdrTextUpperDistItem( 100 ) );
145cdf0e10cSrcweir     aItemSet.Put( SdrTextLowerDistItem( 100 ) );
146cdf0e10cSrcweir     aItemSet.Put( SdrTextAutoGrowWidthItem( sal_False ) );
147cdf0e10cSrcweir     aItemSet.Put( SdrTextAutoGrowHeightItem( sal_True ) );
148cdf0e10cSrcweir     // #78943# use the default cell style to be able to modify the caption font
149cdf0e10cSrcweir     const ScPatternAttr& rDefPattern = static_cast< const ScPatternAttr& >( rDoc.GetPool()->GetDefaultItem( ATTR_PATTERN ) );
150cdf0e10cSrcweir     rDefPattern.FillEditItemSet( &aItemSet );
151cdf0e10cSrcweir 
152cdf0e10cSrcweir     rCaption.SetMergedItemSet( aItemSet );
153cdf0e10cSrcweir }
154cdf0e10cSrcweir 
SetCaptionItems(SdrCaptionObj & rCaption,const SfxItemSet & rItemSet)155cdf0e10cSrcweir void ScCaptionUtil::SetCaptionItems( SdrCaptionObj& rCaption, const SfxItemSet& rItemSet )
156cdf0e10cSrcweir {
157cdf0e10cSrcweir     // copy all items
158cdf0e10cSrcweir     rCaption.SetMergedItemSet( rItemSet );
159cdf0e10cSrcweir     // reset shadow items
160cdf0e10cSrcweir     rCaption.SetMergedItem( SdrShadowItem( sal_False ) );
161cdf0e10cSrcweir     rCaption.SetMergedItem( SdrShadowXDistItem( 100 ) );
162cdf0e10cSrcweir     rCaption.SetMergedItem( SdrShadowYDistItem( 100 ) );
163cdf0e10cSrcweir     rCaption.SetSpecialTextBoxShadow();
164cdf0e10cSrcweir }
165cdf0e10cSrcweir 
166cdf0e10cSrcweir // ============================================================================
167cdf0e10cSrcweir 
168cdf0e10cSrcweir /** Helper for creation and manipulation of caption drawing objects independent
169cdf0e10cSrcweir     from cell annotations. */
170cdf0e10cSrcweir class ScCaptionCreator
171cdf0e10cSrcweir {
172cdf0e10cSrcweir public:
173cdf0e10cSrcweir     /** Create a new caption. The caption will not be inserted into the document. */
174cdf0e10cSrcweir     explicit            ScCaptionCreator( ScDocument& rDoc, const ScAddress& rPos, bool bShown, bool bTailFront );
175cdf0e10cSrcweir     /** Manipulate an existing caption. */
176cdf0e10cSrcweir     explicit            ScCaptionCreator( ScDocument& rDoc, const ScAddress& rPos, SdrCaptionObj& rCaption );
177cdf0e10cSrcweir 
178cdf0e10cSrcweir     /** Returns the drawing layer page of the sheet contained in maPos. */
179cdf0e10cSrcweir     SdrPage*            GetDrawPage();
180cdf0e10cSrcweir     /** Returns the caption drawing obejct. */
GetCaption()181cdf0e10cSrcweir     inline SdrCaptionObj* GetCaption() { return mpCaption; }
182cdf0e10cSrcweir 
183cdf0e10cSrcweir     /** Moves the caption inside the passed rectangle. Uses page area if 0 is passed. */
184cdf0e10cSrcweir     void                FitCaptionToRect( const Rectangle* pVisRect = 0 );
185cdf0e10cSrcweir     /** Places the caption inside the passed rectangle, tries to keep the cell rectangle uncovered. Uses page area if 0 is passed. */
186cdf0e10cSrcweir     void                AutoPlaceCaption( const Rectangle* pVisRect = 0 );
187cdf0e10cSrcweir     /** Updates caption tail and textbox according to current cell position. Uses page area if 0 is passed. */
188cdf0e10cSrcweir     void                UpdateCaptionPos( const Rectangle* pVisRect = 0 );
189cdf0e10cSrcweir 
190cdf0e10cSrcweir protected:
191cdf0e10cSrcweir     /** Helper constructor for derived classes. */
192cdf0e10cSrcweir     explicit            ScCaptionCreator( ScDocument& rDoc, const ScAddress& rPos );
193cdf0e10cSrcweir 
194cdf0e10cSrcweir     /** Calculates the caption tail position according to current cell position. */
195cdf0e10cSrcweir     Point               CalcTailPos( bool bTailFront );
196cdf0e10cSrcweir     /** Implements creation of the caption object. The caption will not be inserted into the document. */
197cdf0e10cSrcweir     void                CreateCaption( bool bShown, bool bTailFront );
198cdf0e10cSrcweir 
199cdf0e10cSrcweir private:
200cdf0e10cSrcweir     /** Initializes all members. */
201cdf0e10cSrcweir     void                Initialize();
202cdf0e10cSrcweir     /** Returns the passed rectangle if existing, page rectangle otherwise. */
GetVisRect(const Rectangle * pVisRect) const203cdf0e10cSrcweir     inline const Rectangle& GetVisRect( const Rectangle* pVisRect ) const { return pVisRect ? *pVisRect : maPageRect; }
204cdf0e10cSrcweir 
205cdf0e10cSrcweir private:
206cdf0e10cSrcweir     ScDocument&         mrDoc;
207cdf0e10cSrcweir     ScAddress           maPos;
208cdf0e10cSrcweir     SdrCaptionObj*      mpCaption;
209cdf0e10cSrcweir     Rectangle           maPageRect;
210cdf0e10cSrcweir     Rectangle           maCellRect;
211cdf0e10cSrcweir     bool                mbNegPage;
212cdf0e10cSrcweir };
213cdf0e10cSrcweir 
214cdf0e10cSrcweir // ----------------------------------------------------------------------------
215cdf0e10cSrcweir 
ScCaptionCreator(ScDocument & rDoc,const ScAddress & rPos,bool bShown,bool bTailFront)216cdf0e10cSrcweir ScCaptionCreator::ScCaptionCreator( ScDocument& rDoc, const ScAddress& rPos, bool bShown, bool bTailFront ) :
217cdf0e10cSrcweir     mrDoc( rDoc ),
218cdf0e10cSrcweir     maPos( rPos ),
219cdf0e10cSrcweir     mpCaption( 0 )
220cdf0e10cSrcweir {
221cdf0e10cSrcweir     Initialize();
222cdf0e10cSrcweir     CreateCaption( bShown, bTailFront );
223cdf0e10cSrcweir }
224cdf0e10cSrcweir 
ScCaptionCreator(ScDocument & rDoc,const ScAddress & rPos,SdrCaptionObj & rCaption)225cdf0e10cSrcweir ScCaptionCreator::ScCaptionCreator( ScDocument& rDoc, const ScAddress& rPos, SdrCaptionObj& rCaption ) :
226cdf0e10cSrcweir     mrDoc( rDoc ),
227cdf0e10cSrcweir     maPos( rPos ),
228cdf0e10cSrcweir     mpCaption( &rCaption )
229cdf0e10cSrcweir {
230cdf0e10cSrcweir     Initialize();
231cdf0e10cSrcweir }
232cdf0e10cSrcweir 
ScCaptionCreator(ScDocument & rDoc,const ScAddress & rPos)233cdf0e10cSrcweir ScCaptionCreator::ScCaptionCreator( ScDocument& rDoc, const ScAddress& rPos ) :
234cdf0e10cSrcweir     mrDoc( rDoc ),
235cdf0e10cSrcweir     maPos( rPos ),
236cdf0e10cSrcweir     mpCaption( 0 )
237cdf0e10cSrcweir {
238cdf0e10cSrcweir     Initialize();
239cdf0e10cSrcweir }
240cdf0e10cSrcweir 
GetDrawPage()241cdf0e10cSrcweir SdrPage* ScCaptionCreator::GetDrawPage()
242cdf0e10cSrcweir {
243cdf0e10cSrcweir     ScDrawLayer* pDrawLayer = mrDoc.GetDrawLayer();
244cdf0e10cSrcweir     return pDrawLayer ? pDrawLayer->GetPage( static_cast< sal_uInt16 >( maPos.Tab() ) ) : 0;
245cdf0e10cSrcweir }
246cdf0e10cSrcweir 
FitCaptionToRect(const Rectangle * pVisRect)247cdf0e10cSrcweir void ScCaptionCreator::FitCaptionToRect( const Rectangle* pVisRect )
248cdf0e10cSrcweir {
249cdf0e10cSrcweir     const Rectangle& rVisRect = GetVisRect( pVisRect );
250cdf0e10cSrcweir 
251cdf0e10cSrcweir     // tail position
252cdf0e10cSrcweir     Point aTailPos = mpCaption->GetTailPos();
253cdf0e10cSrcweir     aTailPos.X() = ::std::max( ::std::min( aTailPos.X(), rVisRect.Right() ), rVisRect.Left() );
254cdf0e10cSrcweir     aTailPos.Y() = ::std::max( ::std::min( aTailPos.Y(), rVisRect.Bottom() ), rVisRect.Top() );
255cdf0e10cSrcweir     mpCaption->SetTailPos( aTailPos );
256cdf0e10cSrcweir 
257cdf0e10cSrcweir     // caption rectangle
258cdf0e10cSrcweir     Rectangle aCaptRect = mpCaption->GetLogicRect();
259cdf0e10cSrcweir     Point aCaptPos = aCaptRect.TopLeft();
260cdf0e10cSrcweir     // move textbox inside right border of visible area
261cdf0e10cSrcweir     aCaptPos.X() = ::std::min< long >( aCaptPos.X(), rVisRect.Right() - aCaptRect.GetWidth() );
262cdf0e10cSrcweir     // move textbox inside left border of visible area (this may move it outside on right side again)
263cdf0e10cSrcweir     aCaptPos.X() = ::std::max< long >( aCaptPos.X(), rVisRect.Left() );
264cdf0e10cSrcweir     // move textbox inside bottom border of visible area
265cdf0e10cSrcweir     aCaptPos.Y() = ::std::min< long >( aCaptPos.Y(), rVisRect.Bottom() - aCaptRect.GetHeight() );
266cdf0e10cSrcweir     // move textbox inside top border of visible area (this may move it outside on bottom side again)
267cdf0e10cSrcweir     aCaptPos.Y() = ::std::max< long >( aCaptPos.Y(), rVisRect.Top() );
268cdf0e10cSrcweir     // update caption
269cdf0e10cSrcweir     aCaptRect.SetPos( aCaptPos );
270cdf0e10cSrcweir     mpCaption->SetLogicRect( aCaptRect );
271cdf0e10cSrcweir }
272cdf0e10cSrcweir 
AutoPlaceCaption(const Rectangle * pVisRect)273cdf0e10cSrcweir void ScCaptionCreator::AutoPlaceCaption( const Rectangle* pVisRect )
274cdf0e10cSrcweir {
275cdf0e10cSrcweir     const Rectangle& rVisRect = GetVisRect( pVisRect );
276cdf0e10cSrcweir 
277cdf0e10cSrcweir     // caption rectangle
278cdf0e10cSrcweir     Rectangle aCaptRect = mpCaption->GetLogicRect();
279cdf0e10cSrcweir     long nWidth = aCaptRect.GetWidth();
280cdf0e10cSrcweir     long nHeight = aCaptRect.GetHeight();
281cdf0e10cSrcweir 
282cdf0e10cSrcweir     // n***Space contains available space between border of visible area and cell
283cdf0e10cSrcweir     long nLeftSpace = maCellRect.Left() - rVisRect.Left() + 1;
284cdf0e10cSrcweir     long nRightSpace = rVisRect.Right() - maCellRect.Right() + 1;
285cdf0e10cSrcweir     long nTopSpace = maCellRect.Top() - rVisRect.Top() + 1;
286cdf0e10cSrcweir     long nBottomSpace = rVisRect.Bottom() - maCellRect.Bottom() + 1;
287cdf0e10cSrcweir 
288cdf0e10cSrcweir     // nNeeded*** contains textbox dimensions plus needed distances to cell or border of visible area
289cdf0e10cSrcweir     long nNeededSpaceX = nWidth + SC_NOTECAPTION_CELLDIST;
290cdf0e10cSrcweir     long nNeededSpaceY = nHeight + SC_NOTECAPTION_CELLDIST;
291cdf0e10cSrcweir 
292cdf0e10cSrcweir     // bFitsWidth*** == true means width of textbox fits into horizontal free space of visible area
293cdf0e10cSrcweir     bool bFitsWidthLeft = nNeededSpaceX <= nLeftSpace;      // text box width fits into the width left of cell
294cdf0e10cSrcweir     bool bFitsWidthRight = nNeededSpaceX <= nRightSpace;    // text box width fits into the width right of cell
295cdf0e10cSrcweir     bool bFitsWidth = nWidth <= rVisRect.GetWidth();        // text box width fits into width of visible area
296cdf0e10cSrcweir 
297cdf0e10cSrcweir     // bFitsHeight*** == true means height of textbox fits into vertical free space of visible area
298cdf0e10cSrcweir     bool bFitsHeightTop = nNeededSpaceY <= nTopSpace;       // text box height fits into the height above cell
299cdf0e10cSrcweir     bool bFitsHeightBottom = nNeededSpaceY <= nBottomSpace; // text box height fits into the height below cell
300cdf0e10cSrcweir     bool bFitsHeight = nHeight <= rVisRect.GetHeight();     // text box height fits into height of visible area
301cdf0e10cSrcweir 
302cdf0e10cSrcweir     // bFits*** == true means the textbox fits completely into free space of visible area
303cdf0e10cSrcweir     bool bFitsLeft = bFitsWidthLeft && bFitsHeight;
304cdf0e10cSrcweir     bool bFitsRight = bFitsWidthRight && bFitsHeight;
305cdf0e10cSrcweir     bool bFitsTop = bFitsWidth && bFitsHeightTop;
306cdf0e10cSrcweir     bool bFitsBottom = bFitsWidth && bFitsHeightBottom;
307cdf0e10cSrcweir 
308cdf0e10cSrcweir     Point aCaptPos;
309cdf0e10cSrcweir     // use left/right placement if possible, or if top/bottom placement not possible
310cdf0e10cSrcweir     if( bFitsLeft || bFitsRight || (!bFitsTop && !bFitsBottom) )
311cdf0e10cSrcweir     {
312cdf0e10cSrcweir         // prefer left in RTL sheet and right in LTR sheets
313cdf0e10cSrcweir         bool bPreferLeft = bFitsLeft && (mbNegPage || !bFitsRight);
314cdf0e10cSrcweir         bool bPreferRight = bFitsRight && (!mbNegPage || !bFitsLeft);
315cdf0e10cSrcweir         // move to left, if left is preferred, or if neither left nor right fit and there is more space to the left
316cdf0e10cSrcweir         if( bPreferLeft || (!bPreferRight && (nLeftSpace > nRightSpace)) )
317cdf0e10cSrcweir             aCaptPos.X() = maCellRect.Left() - SC_NOTECAPTION_CELLDIST - nWidth;
318cdf0e10cSrcweir         else // to right
319cdf0e10cSrcweir             aCaptPos.X() = maCellRect.Right() + SC_NOTECAPTION_CELLDIST;
320cdf0e10cSrcweir         // Y position according to top cell border
321cdf0e10cSrcweir         aCaptPos.Y() = maCellRect.Top() + SC_NOTECAPTION_OFFSET_Y;
322cdf0e10cSrcweir     }
323cdf0e10cSrcweir     else    // top or bottom placement
324cdf0e10cSrcweir     {
325cdf0e10cSrcweir         // X position
326cdf0e10cSrcweir         aCaptPos.X() = maCellRect.Left() + SC_NOTECAPTION_OFFSET_X;
327cdf0e10cSrcweir         // top placement, if possible
328cdf0e10cSrcweir         if( bFitsTop )
329cdf0e10cSrcweir             aCaptPos.Y() = maCellRect.Top() - SC_NOTECAPTION_CELLDIST - nHeight;
330cdf0e10cSrcweir         else    // bottom placement
331cdf0e10cSrcweir             aCaptPos.Y() = maCellRect.Bottom() + SC_NOTECAPTION_CELLDIST;
332cdf0e10cSrcweir     }
333cdf0e10cSrcweir 
334cdf0e10cSrcweir     // update textbox position in note caption object
335cdf0e10cSrcweir     aCaptRect.SetPos( aCaptPos );
336cdf0e10cSrcweir     mpCaption->SetLogicRect( aCaptRect );
337cdf0e10cSrcweir     FitCaptionToRect( pVisRect );
338cdf0e10cSrcweir }
339cdf0e10cSrcweir 
UpdateCaptionPos(const Rectangle * pVisRect)340cdf0e10cSrcweir void ScCaptionCreator::UpdateCaptionPos( const Rectangle* pVisRect )
341cdf0e10cSrcweir {
342cdf0e10cSrcweir     ScDrawLayer* pDrawLayer = mrDoc.GetDrawLayer();
343cdf0e10cSrcweir 
344cdf0e10cSrcweir     // update caption position
345cdf0e10cSrcweir     const Point& rOldTailPos = mpCaption->GetTailPos();
346cdf0e10cSrcweir     Point aTailPos = CalcTailPos( false );
347cdf0e10cSrcweir     if( rOldTailPos != aTailPos )
348cdf0e10cSrcweir     {
349cdf0e10cSrcweir         // create drawing undo action
350*577c0052SWang Lei         if( pDrawLayer )
351*577c0052SWang Lei             if( pDrawLayer->IsUndoAllowed() )
352*577c0052SWang Lei                 if( pDrawLayer->IsRecording() )
353cdf0e10cSrcweir                     pDrawLayer->AddCalcUndo( pDrawLayer->GetSdrUndoFactory().CreateUndoGeoObject( *mpCaption ) );
354*577c0052SWang Lei 
355cdf0e10cSrcweir         // calculate new caption rectangle (#i98141# handle LTR<->RTL switch correctly)
356cdf0e10cSrcweir         Rectangle aCaptRect = mpCaption->GetLogicRect();
357cdf0e10cSrcweir         long nDiffX = (rOldTailPos.X() >= 0) ? (aCaptRect.Left() - rOldTailPos.X()) : (rOldTailPos.X() - aCaptRect.Right());
358cdf0e10cSrcweir         if( mbNegPage ) nDiffX = -nDiffX - aCaptRect.GetWidth();
359cdf0e10cSrcweir         long nDiffY = aCaptRect.Top() - rOldTailPos.Y();
360cdf0e10cSrcweir         aCaptRect.SetPos( aTailPos + Point( nDiffX, nDiffY ) );
361cdf0e10cSrcweir         // set new tail position and caption rectangle
362cdf0e10cSrcweir         mpCaption->SetTailPos( aTailPos );
363cdf0e10cSrcweir         mpCaption->SetLogicRect( aCaptRect );
364cdf0e10cSrcweir         // fit caption into draw page
365cdf0e10cSrcweir         FitCaptionToRect( pVisRect );
366cdf0e10cSrcweir     }
367cdf0e10cSrcweir 
368cdf0e10cSrcweir     // update cell position in caption user data
369cdf0e10cSrcweir     ScDrawObjData* pCaptData = ScDrawLayer::GetNoteCaptionData( mpCaption, maPos.Tab() );
370cdf0e10cSrcweir     if( pCaptData && (maPos != pCaptData->maStart) )
371cdf0e10cSrcweir     {
372cdf0e10cSrcweir         // create drawing undo action
373cdf0e10cSrcweir         if( pDrawLayer && pDrawLayer->IsRecording() )
374*577c0052SWang Lei             pDrawLayer->AddCalcUndo< ScUndoObjData >(mpCaption, pCaptData->maStart, pCaptData->maEnd, maPos, pCaptData->maEnd );
375cdf0e10cSrcweir         // set new position
376cdf0e10cSrcweir         pCaptData->maStart = maPos;
377cdf0e10cSrcweir     }
378cdf0e10cSrcweir }
379cdf0e10cSrcweir 
CalcTailPos(bool bTailFront)380cdf0e10cSrcweir Point ScCaptionCreator::CalcTailPos( bool bTailFront )
381cdf0e10cSrcweir {
382cdf0e10cSrcweir     // tail position
383cdf0e10cSrcweir     bool bTailLeft = bTailFront != mbNegPage;
384cdf0e10cSrcweir     Point aTailPos = bTailLeft ? maCellRect.TopLeft() : maCellRect.TopRight();
385cdf0e10cSrcweir     // move caption point 1/10 mm inside cell
386cdf0e10cSrcweir     if( bTailLeft ) aTailPos.X() += 10; else aTailPos.X() -= 10;
387cdf0e10cSrcweir     aTailPos.Y() += 10;
388cdf0e10cSrcweir     return aTailPos;
389cdf0e10cSrcweir }
390cdf0e10cSrcweir 
CreateCaption(bool bShown,bool bTailFront)391cdf0e10cSrcweir void ScCaptionCreator::CreateCaption( bool bShown, bool bTailFront )
392cdf0e10cSrcweir {
393cdf0e10cSrcweir     // create the caption drawing object
394cdf0e10cSrcweir     Rectangle aTextRect( Point( 0 , 0 ), Size( SC_NOTECAPTION_WIDTH, SC_NOTECAPTION_HEIGHT ) );
395cdf0e10cSrcweir     Point aTailPos = CalcTailPos( bTailFront );
396cdf0e10cSrcweir     mpCaption = new SdrCaptionObj( aTextRect, aTailPos );
397cdf0e10cSrcweir     // basic caption settings
398cdf0e10cSrcweir     ScCaptionUtil::SetBasicCaptionSettings( *mpCaption, bShown );
399cdf0e10cSrcweir }
400cdf0e10cSrcweir 
Initialize()401cdf0e10cSrcweir void ScCaptionCreator::Initialize()
402cdf0e10cSrcweir {
403cdf0e10cSrcweir     maCellRect = ScDrawLayer::GetCellRect( mrDoc, maPos, true );
404cdf0e10cSrcweir     mbNegPage = mrDoc.IsNegativePage( maPos.Tab() );
405cdf0e10cSrcweir     if( SdrPage* pDrawPage = GetDrawPage() )
406cdf0e10cSrcweir     {
407cdf0e10cSrcweir         maPageRect = Rectangle( Point( 0, 0 ), pDrawPage->GetSize() );
408cdf0e10cSrcweir         /*  #i98141# SdrPage::GetSize() returns negative width in RTL mode.
409cdf0e10cSrcweir             The call to Rectangle::Adjust() orders left/right coordinate
410cdf0e10cSrcweir             accordingly. */
411cdf0e10cSrcweir         maPageRect.Justify();
412cdf0e10cSrcweir     }
413cdf0e10cSrcweir }
414cdf0e10cSrcweir 
415cdf0e10cSrcweir // ============================================================================
416cdf0e10cSrcweir 
417cdf0e10cSrcweir /** Helper for creation of permanent caption drawing objects for cell notes. */
418cdf0e10cSrcweir class ScNoteCaptionCreator : public ScCaptionCreator
419cdf0e10cSrcweir {
420cdf0e10cSrcweir public:
421cdf0e10cSrcweir     /** Create a new caption object and inserts it into the document. */
422cdf0e10cSrcweir     explicit            ScNoteCaptionCreator( ScDocument& rDoc, const ScAddress& rPos, ScNoteData& rNoteData );
423cdf0e10cSrcweir     /** Manipulate an existing caption. */
424cdf0e10cSrcweir     explicit            ScNoteCaptionCreator( ScDocument& rDoc, const ScAddress& rPos, SdrCaptionObj& rCaption, bool bShown );
425cdf0e10cSrcweir };
426cdf0e10cSrcweir 
427cdf0e10cSrcweir // ----------------------------------------------------------------------------
428cdf0e10cSrcweir 
ScNoteCaptionCreator(ScDocument & rDoc,const ScAddress & rPos,ScNoteData & rNoteData)429cdf0e10cSrcweir ScNoteCaptionCreator::ScNoteCaptionCreator( ScDocument& rDoc, const ScAddress& rPos, ScNoteData& rNoteData ) :
430cdf0e10cSrcweir     ScCaptionCreator( rDoc, rPos )  // use helper c'tor that does not create the caption yet
431cdf0e10cSrcweir {
432cdf0e10cSrcweir     SdrPage* pDrawPage = GetDrawPage();
433cdf0e10cSrcweir     OSL_ENSURE( pDrawPage, "ScNoteCaptionCreator::ScNoteCaptionCreator - no drawing page" );
434cdf0e10cSrcweir     if( pDrawPage )
435cdf0e10cSrcweir     {
436cdf0e10cSrcweir         // create the caption drawing object
437cdf0e10cSrcweir         CreateCaption( rNoteData.mbShown, false );
438cdf0e10cSrcweir         rNoteData.mpCaption = GetCaption();
439cdf0e10cSrcweir         OSL_ENSURE( rNoteData.mpCaption, "ScNoteCaptionCreator::ScNoteCaptionCreator - missing caption object" );
440cdf0e10cSrcweir         if( rNoteData.mpCaption )
441cdf0e10cSrcweir         {
442cdf0e10cSrcweir             // store note position in user data of caption object
443cdf0e10cSrcweir             ScCaptionUtil::SetCaptionUserData( *rNoteData.mpCaption, rPos );
444cdf0e10cSrcweir             // insert object into draw page
445cdf0e10cSrcweir             pDrawPage->InsertObject( rNoteData.mpCaption );
446cdf0e10cSrcweir         }
447cdf0e10cSrcweir     }
448cdf0e10cSrcweir }
449cdf0e10cSrcweir 
ScNoteCaptionCreator(ScDocument & rDoc,const ScAddress & rPos,SdrCaptionObj & rCaption,bool bShown)450cdf0e10cSrcweir ScNoteCaptionCreator::ScNoteCaptionCreator( ScDocument& rDoc, const ScAddress& rPos, SdrCaptionObj& rCaption, bool bShown ) :
451cdf0e10cSrcweir     ScCaptionCreator( rDoc, rPos, rCaption )
452cdf0e10cSrcweir {
453cdf0e10cSrcweir     SdrPage* pDrawPage = GetDrawPage();
454cdf0e10cSrcweir     OSL_ENSURE( pDrawPage, "ScNoteCaptionCreator::ScNoteCaptionCreator - no drawing page" );
455cdf0e10cSrcweir     OSL_ENSURE( rCaption.GetPage() == pDrawPage, "ScNoteCaptionCreator::ScNoteCaptionCreator - wrong drawing page in caption" );
456cdf0e10cSrcweir     if( pDrawPage && (rCaption.GetPage() == pDrawPage) )
457cdf0e10cSrcweir     {
458cdf0e10cSrcweir         // store note position in user data of caption object
459cdf0e10cSrcweir         ScCaptionUtil::SetCaptionUserData( rCaption, rPos );
460cdf0e10cSrcweir         // basic caption settings
461cdf0e10cSrcweir         ScCaptionUtil::SetBasicCaptionSettings( rCaption, bShown );
462cdf0e10cSrcweir         // set correct tail position
463cdf0e10cSrcweir         rCaption.SetTailPos( CalcTailPos( false ) );
464cdf0e10cSrcweir     }
465cdf0e10cSrcweir }
466cdf0e10cSrcweir 
467cdf0e10cSrcweir } // namespace
468cdf0e10cSrcweir 
469cdf0e10cSrcweir // ============================================================================
470cdf0e10cSrcweir 
471cdf0e10cSrcweir struct ScCaptionInitData
472cdf0e10cSrcweir {
473cdf0e10cSrcweir     typedef ::std::auto_ptr< SfxItemSet >           SfxItemSetPtr;
474cdf0e10cSrcweir     typedef ::std::auto_ptr< OutlinerParaObject >   OutlinerParaObjPtr;
475cdf0e10cSrcweir 
476cdf0e10cSrcweir     SfxItemSetPtr       mxItemSet;          /// Caption object formatting.
477cdf0e10cSrcweir     OutlinerParaObjPtr  mxOutlinerObj;      /// Text object with all text portion formatting.
478cdf0e10cSrcweir     ::rtl::OUString     maSimpleText;       /// Simple text without formatting.
479cdf0e10cSrcweir     Point               maCaptionOffset;    /// Caption position relative to cell corner.
480cdf0e10cSrcweir     Size                maCaptionSize;      /// Size of the caption object.
481cdf0e10cSrcweir     bool                mbDefaultPosSize;   /// True = use default position and size for caption.
482cdf0e10cSrcweir 
483cdf0e10cSrcweir     explicit            ScCaptionInitData();
484cdf0e10cSrcweir };
485cdf0e10cSrcweir 
486cdf0e10cSrcweir // ----------------------------------------------------------------------------
487cdf0e10cSrcweir 
ScCaptionInitData()488cdf0e10cSrcweir ScCaptionInitData::ScCaptionInitData() :
489cdf0e10cSrcweir     mbDefaultPosSize( true )
490cdf0e10cSrcweir {
491cdf0e10cSrcweir }
492cdf0e10cSrcweir 
493cdf0e10cSrcweir // ============================================================================
494cdf0e10cSrcweir 
ScNoteData(bool bShown)495cdf0e10cSrcweir ScNoteData::ScNoteData( bool bShown ) :
496cdf0e10cSrcweir     mpCaption( 0 ),
497cdf0e10cSrcweir     mbShown( bShown )
498cdf0e10cSrcweir {
499cdf0e10cSrcweir }
500cdf0e10cSrcweir 
~ScNoteData()501cdf0e10cSrcweir ScNoteData::~ScNoteData()
502cdf0e10cSrcweir {
503cdf0e10cSrcweir }
504cdf0e10cSrcweir 
505cdf0e10cSrcweir // ============================================================================
506cdf0e10cSrcweir 
ScPostIt(ScDocument & rDoc,const ScAddress & rPos,bool bShown)507cdf0e10cSrcweir ScPostIt::ScPostIt( ScDocument& rDoc, const ScAddress& rPos, bool bShown ) :
508cdf0e10cSrcweir     mrDoc( rDoc ),
509cdf0e10cSrcweir     maNoteData( bShown )
510cdf0e10cSrcweir {
511cdf0e10cSrcweir     AutoStamp();
512cdf0e10cSrcweir     CreateCaption( rPos );
513cdf0e10cSrcweir }
514cdf0e10cSrcweir 
ScPostIt(ScDocument & rDoc,const ScAddress & rPos,const ScPostIt & rNote)515cdf0e10cSrcweir ScPostIt::ScPostIt( ScDocument& rDoc, const ScAddress& rPos, const ScPostIt& rNote ) :
516cdf0e10cSrcweir     mrDoc( rDoc ),
517cdf0e10cSrcweir     maNoteData( rNote.maNoteData )
518cdf0e10cSrcweir {
519cdf0e10cSrcweir     maNoteData.mpCaption = 0;
520cdf0e10cSrcweir     CreateCaption( rPos, rNote.maNoteData.mpCaption );
521cdf0e10cSrcweir }
522cdf0e10cSrcweir 
ScPostIt(ScDocument & rDoc,const ScAddress & rPos,const ScNoteData & rNoteData,bool bAlwaysCreateCaption)523cdf0e10cSrcweir ScPostIt::ScPostIt( ScDocument& rDoc, const ScAddress& rPos, const ScNoteData& rNoteData, bool bAlwaysCreateCaption ) :
524cdf0e10cSrcweir     mrDoc( rDoc ),
525cdf0e10cSrcweir     maNoteData( rNoteData )
526cdf0e10cSrcweir {
527cdf0e10cSrcweir     if( bAlwaysCreateCaption || maNoteData.mbShown )
528cdf0e10cSrcweir         CreateCaptionFromInitData( rPos );
529cdf0e10cSrcweir }
530cdf0e10cSrcweir 
~ScPostIt()531cdf0e10cSrcweir ScPostIt::~ScPostIt()
532cdf0e10cSrcweir {
533cdf0e10cSrcweir     RemoveCaption();
534cdf0e10cSrcweir }
535cdf0e10cSrcweir 
Clone(const ScAddress & rOwnPos,ScDocument & rDestDoc,const ScAddress & rDestPos,bool bCloneCaption) const536cdf0e10cSrcweir ScPostIt* ScPostIt::Clone( const ScAddress& rOwnPos, ScDocument& rDestDoc, const ScAddress& rDestPos, bool bCloneCaption ) const
537cdf0e10cSrcweir {
538cdf0e10cSrcweir     CreateCaptionFromInitData( rOwnPos );
539cdf0e10cSrcweir     return bCloneCaption ? new ScPostIt( rDestDoc, rDestPos, *this ) : new ScPostIt( rDestDoc, rDestPos, maNoteData, false );
540cdf0e10cSrcweir }
541cdf0e10cSrcweir 
AutoStamp()542cdf0e10cSrcweir void ScPostIt::AutoStamp()
543cdf0e10cSrcweir {
544cdf0e10cSrcweir     maNoteData.maDate = ScGlobal::pLocaleData->getDate( Date() );
545cdf0e10cSrcweir     maNoteData.maAuthor = SvtUserOptions().GetID();
546cdf0e10cSrcweir }
547cdf0e10cSrcweir 
GetOutlinerObject() const548cdf0e10cSrcweir const OutlinerParaObject* ScPostIt::GetOutlinerObject() const
549cdf0e10cSrcweir {
550cdf0e10cSrcweir     if( maNoteData.mpCaption )
551cdf0e10cSrcweir         return maNoteData.mpCaption->GetOutlinerParaObject();
552cdf0e10cSrcweir     if( maNoteData.mxInitData.get() )
553cdf0e10cSrcweir         return maNoteData.mxInitData->mxOutlinerObj.get();
554cdf0e10cSrcweir     return 0;
555cdf0e10cSrcweir }
556cdf0e10cSrcweir 
GetEditTextObject() const557cdf0e10cSrcweir const EditTextObject* ScPostIt::GetEditTextObject() const
558cdf0e10cSrcweir {
559cdf0e10cSrcweir     const OutlinerParaObject* pOPO = GetOutlinerObject();
560cdf0e10cSrcweir     return pOPO ? &pOPO->GetTextObject() : 0;
561cdf0e10cSrcweir }
562cdf0e10cSrcweir 
GetText() const563cdf0e10cSrcweir OUString ScPostIt::GetText() const
564cdf0e10cSrcweir {
565cdf0e10cSrcweir     if( const EditTextObject* pEditObj = GetEditTextObject() )
566cdf0e10cSrcweir     {
567cdf0e10cSrcweir         OUStringBuffer aBuffer;
568cdf0e10cSrcweir         for( sal_uInt16 nPara = 0, nParaCount = pEditObj->GetParagraphCount(); nPara < nParaCount; ++nPara )
569cdf0e10cSrcweir         {
570cdf0e10cSrcweir             if( nPara > 0 )
571cdf0e10cSrcweir                 aBuffer.append( sal_Unicode( '\n' ) );
572cdf0e10cSrcweir             aBuffer.append( pEditObj->GetText( nPara ) );
573cdf0e10cSrcweir         }
574cdf0e10cSrcweir         return aBuffer.makeStringAndClear();
575cdf0e10cSrcweir     }
576cdf0e10cSrcweir     if( maNoteData.mxInitData.get() )
577cdf0e10cSrcweir         return maNoteData.mxInitData->maSimpleText;
578cdf0e10cSrcweir     return OUString();
579cdf0e10cSrcweir }
580cdf0e10cSrcweir 
HasMultiLineText() const581cdf0e10cSrcweir bool ScPostIt::HasMultiLineText() const
582cdf0e10cSrcweir {
583cdf0e10cSrcweir     if( const EditTextObject* pEditObj = GetEditTextObject() )
584cdf0e10cSrcweir         return pEditObj->GetParagraphCount() > 1;
585cdf0e10cSrcweir     if( maNoteData.mxInitData.get() )
586cdf0e10cSrcweir         return maNoteData.mxInitData->maSimpleText.indexOf( '\n' ) >= 0;
587cdf0e10cSrcweir     return false;
588cdf0e10cSrcweir }
589cdf0e10cSrcweir 
SetText(const ScAddress & rPos,const OUString & rText)590cdf0e10cSrcweir void ScPostIt::SetText( const ScAddress& rPos, const OUString& rText )
591cdf0e10cSrcweir {
592cdf0e10cSrcweir     CreateCaptionFromInitData( rPos );
593cdf0e10cSrcweir     if( maNoteData.mpCaption )
594cdf0e10cSrcweir         maNoteData.mpCaption->SetText( rText );
595cdf0e10cSrcweir }
596cdf0e10cSrcweir 
GetOrCreateCaption(const ScAddress & rPos) const597cdf0e10cSrcweir SdrCaptionObj* ScPostIt::GetOrCreateCaption( const ScAddress& rPos ) const
598cdf0e10cSrcweir {
599cdf0e10cSrcweir     CreateCaptionFromInitData( rPos );
600cdf0e10cSrcweir     return maNoteData.mpCaption;
601cdf0e10cSrcweir }
602cdf0e10cSrcweir 
ForgetCaption()603cdf0e10cSrcweir void ScPostIt::ForgetCaption()
604cdf0e10cSrcweir {
605cdf0e10cSrcweir     /*  This function is used in undo actions to give up the responsibility for
606cdf0e10cSrcweir         the caption object which is handled by separate drawing undo actions. */
607cdf0e10cSrcweir     maNoteData.mpCaption = 0;
608cdf0e10cSrcweir     maNoteData.mxInitData.reset();
609cdf0e10cSrcweir }
610cdf0e10cSrcweir 
ShowCaption(const ScAddress & rPos,bool bShow)611cdf0e10cSrcweir void ScPostIt::ShowCaption( const ScAddress& rPos, bool bShow )
612cdf0e10cSrcweir {
613cdf0e10cSrcweir     CreateCaptionFromInitData( rPos );
614cdf0e10cSrcweir     // no separate drawing undo needed, handled completely inside ScUndoShowHideNote
615cdf0e10cSrcweir     maNoteData.mbShown = bShow;
616cdf0e10cSrcweir     if( maNoteData.mpCaption )
617cdf0e10cSrcweir         ScCaptionUtil::SetCaptionLayer( *maNoteData.mpCaption, bShow );
618cdf0e10cSrcweir }
619cdf0e10cSrcweir 
ShowCaptionTemp(const ScAddress & rPos,bool bShow)620cdf0e10cSrcweir void ScPostIt::ShowCaptionTemp( const ScAddress& rPos, bool bShow )
621cdf0e10cSrcweir {
622cdf0e10cSrcweir     CreateCaptionFromInitData( rPos );
623cdf0e10cSrcweir     if( maNoteData.mpCaption )
624cdf0e10cSrcweir         ScCaptionUtil::SetCaptionLayer( *maNoteData.mpCaption, maNoteData.mbShown || bShow );
625cdf0e10cSrcweir }
626cdf0e10cSrcweir 
UpdateCaptionPos(const ScAddress & rPos)627cdf0e10cSrcweir void ScPostIt::UpdateCaptionPos( const ScAddress& rPos )
628cdf0e10cSrcweir {
629cdf0e10cSrcweir     CreateCaptionFromInitData( rPos );
630cdf0e10cSrcweir     if( maNoteData.mpCaption )
631cdf0e10cSrcweir     {
632cdf0e10cSrcweir         ScCaptionCreator aCreator( mrDoc, rPos, *maNoteData.mpCaption );
633cdf0e10cSrcweir         aCreator.UpdateCaptionPos();
634cdf0e10cSrcweir     }
635cdf0e10cSrcweir }
636cdf0e10cSrcweir 
637cdf0e10cSrcweir // private --------------------------------------------------------------------
638cdf0e10cSrcweir 
CreateCaptionFromInitData(const ScAddress & rPos) const639cdf0e10cSrcweir void ScPostIt::CreateCaptionFromInitData( const ScAddress& rPos ) const
640cdf0e10cSrcweir {
641cdf0e10cSrcweir     OSL_ENSURE( maNoteData.mpCaption || maNoteData.mxInitData.get(), "ScPostIt::CreateCaptionFromInitData - need caption object or initial caption data" );
642cdf0e10cSrcweir     if( maNoteData.mxInitData.get() )
643cdf0e10cSrcweir     {
644cdf0e10cSrcweir         /*  This function is called from ScPostIt::Clone() when copying cells
645cdf0e10cSrcweir             to the clipboard/undo document, and when copying cells from the
646cdf0e10cSrcweir             clipboard/undo document. The former should always be called first,
647cdf0e10cSrcweir             so if called in an clipboard/undo document, the caption should have
648cdf0e10cSrcweir             been created already. */
649cdf0e10cSrcweir         OSL_ENSURE( !mrDoc.IsUndo() && !mrDoc.IsClipboard(), "ScPostIt::CreateCaptionFromInitData - note caption should not be created in undo/clip documents" );
650cdf0e10cSrcweir 
651cdf0e10cSrcweir         /*  #i104915# Never try to create notes in Undo document, leads to
652cdf0e10cSrcweir             crash due to missing document members (e.g. row height array). */
653cdf0e10cSrcweir         if( !maNoteData.mpCaption && !mrDoc.IsUndo() )
654cdf0e10cSrcweir         {
655cdf0e10cSrcweir             // ScNoteCaptionCreator c'tor creates the caption and inserts it into the document and maNoteData
656cdf0e10cSrcweir             ScNoteCaptionCreator aCreator( mrDoc, rPos, maNoteData );
657cdf0e10cSrcweir             if( maNoteData.mpCaption )
658cdf0e10cSrcweir             {
659cdf0e10cSrcweir                 ScCaptionInitData& rInitData = *maNoteData.mxInitData;
660cdf0e10cSrcweir 
661cdf0e10cSrcweir                 // transfer ownership of outliner object to caption, or set simple text
662cdf0e10cSrcweir                 OSL_ENSURE( rInitData.mxOutlinerObj.get() || (rInitData.maSimpleText.getLength() > 0),
663cdf0e10cSrcweir                     "ScPostIt::CreateCaptionFromInitData - need either outliner para object or simple text" );
664cdf0e10cSrcweir                 if( rInitData.mxOutlinerObj.get() )
665cdf0e10cSrcweir                     maNoteData.mpCaption->SetOutlinerParaObject( rInitData.mxOutlinerObj.release() );
666cdf0e10cSrcweir                 else
667cdf0e10cSrcweir                     maNoteData.mpCaption->SetText( rInitData.maSimpleText );
668cdf0e10cSrcweir 
669cdf0e10cSrcweir                 // copy all items or set default items; reset shadow items
670cdf0e10cSrcweir                 ScCaptionUtil::SetDefaultItems( *maNoteData.mpCaption, mrDoc );
671cdf0e10cSrcweir                 if( rInitData.mxItemSet.get() )
672cdf0e10cSrcweir                     ScCaptionUtil::SetCaptionItems( *maNoteData.mpCaption, *rInitData.mxItemSet );
673cdf0e10cSrcweir 
674cdf0e10cSrcweir                 // set position and size of the caption object
675cdf0e10cSrcweir                 if( rInitData.mbDefaultPosSize )
676cdf0e10cSrcweir                 {
677cdf0e10cSrcweir                     // set other items and fit caption size to text
678cdf0e10cSrcweir                     maNoteData.mpCaption->SetMergedItem( SdrTextMinFrameWidthItem( SC_NOTECAPTION_WIDTH ) );
679cdf0e10cSrcweir                     maNoteData.mpCaption->SetMergedItem( SdrTextMaxFrameWidthItem( SC_NOTECAPTION_MAXWIDTH_TEMP ) );
680cdf0e10cSrcweir                     maNoteData.mpCaption->AdjustTextFrameWidthAndHeight();
681cdf0e10cSrcweir                     aCreator.AutoPlaceCaption();
682cdf0e10cSrcweir                 }
683cdf0e10cSrcweir                 else
684cdf0e10cSrcweir                 {
685cdf0e10cSrcweir                     Rectangle aCellRect = ScDrawLayer::GetCellRect( mrDoc, rPos, true );
686cdf0e10cSrcweir                     bool bNegPage = mrDoc.IsNegativePage( rPos.Tab() );
687cdf0e10cSrcweir                     long nPosX = bNegPage ? (aCellRect.Left() - rInitData.maCaptionOffset.X()) : (aCellRect.Right() + rInitData.maCaptionOffset.X());
688cdf0e10cSrcweir                     long nPosY = aCellRect.Top() + rInitData.maCaptionOffset.Y();
689cdf0e10cSrcweir                     Rectangle aCaptRect( Point( nPosX, nPosY ), rInitData.maCaptionSize );
690cdf0e10cSrcweir                     maNoteData.mpCaption->SetLogicRect( aCaptRect );
691cdf0e10cSrcweir                     aCreator.FitCaptionToRect();
692cdf0e10cSrcweir                 }
693cdf0e10cSrcweir             }
694cdf0e10cSrcweir         }
695cdf0e10cSrcweir         // forget the initial caption data struct
696cdf0e10cSrcweir         maNoteData.mxInitData.reset();
697cdf0e10cSrcweir     }
698cdf0e10cSrcweir }
699cdf0e10cSrcweir 
CreateCaption(const ScAddress & rPos,const SdrCaptionObj * pCaption)700cdf0e10cSrcweir void ScPostIt::CreateCaption( const ScAddress& rPos, const SdrCaptionObj* pCaption )
701cdf0e10cSrcweir {
702cdf0e10cSrcweir     OSL_ENSURE( !maNoteData.mpCaption, "ScPostIt::CreateCaption - unexpected caption object found" );
703cdf0e10cSrcweir     maNoteData.mpCaption = 0;
704cdf0e10cSrcweir 
705cdf0e10cSrcweir     /*  #i104915# Never try to create notes in Undo document, leads to
706cdf0e10cSrcweir         crash due to missing document members (e.g. row height array). */
707cdf0e10cSrcweir     OSL_ENSURE( !mrDoc.IsUndo(), "ScPostIt::CreateCaption - note caption should not be created in undo documents" );
708cdf0e10cSrcweir     if( mrDoc.IsUndo() )
709cdf0e10cSrcweir         return;
710cdf0e10cSrcweir 
711cdf0e10cSrcweir     // drawing layer may be missing, if a note is copied into a clipboard document
712cdf0e10cSrcweir     if( mrDoc.IsClipboard() )
713cdf0e10cSrcweir         mrDoc.InitDrawLayer();
714cdf0e10cSrcweir 
715cdf0e10cSrcweir     // ScNoteCaptionCreator c'tor creates the caption and inserts it into the document and maNoteData
716cdf0e10cSrcweir     ScNoteCaptionCreator aCreator( mrDoc, rPos, maNoteData );
717cdf0e10cSrcweir     if( maNoteData.mpCaption )
718cdf0e10cSrcweir     {
719cdf0e10cSrcweir         // clone settings of passed caption
720cdf0e10cSrcweir         if( pCaption )
721cdf0e10cSrcweir         {
722cdf0e10cSrcweir             // copy edit text object (object must be inserted into page already)
723cdf0e10cSrcweir             if( OutlinerParaObject* pOPO = pCaption->GetOutlinerParaObject() )
724cdf0e10cSrcweir                 maNoteData.mpCaption->SetOutlinerParaObject( new OutlinerParaObject( *pOPO ) );
725cdf0e10cSrcweir             // copy formatting items (after text has been copied to apply font formatting)
726cdf0e10cSrcweir             maNoteData.mpCaption->SetMergedItemSetAndBroadcast( pCaption->GetMergedItemSet() );
727cdf0e10cSrcweir             // move textbox position relative to new cell, copy textbox size
728cdf0e10cSrcweir             Rectangle aCaptRect = pCaption->GetLogicRect();
729cdf0e10cSrcweir             Point aDist = maNoteData.mpCaption->GetTailPos() - pCaption->GetTailPos();
730cdf0e10cSrcweir             aCaptRect.Move( aDist.X(), aDist.Y() );
731cdf0e10cSrcweir             maNoteData.mpCaption->SetLogicRect( aCaptRect );
732cdf0e10cSrcweir             aCreator.FitCaptionToRect();
733cdf0e10cSrcweir         }
734cdf0e10cSrcweir         else
735cdf0e10cSrcweir         {
736cdf0e10cSrcweir             // set default formatting and default position
737cdf0e10cSrcweir             ScCaptionUtil::SetDefaultItems( *maNoteData.mpCaption, mrDoc );
738cdf0e10cSrcweir             aCreator.AutoPlaceCaption();
739cdf0e10cSrcweir         }
740cdf0e10cSrcweir 
741cdf0e10cSrcweir         // create undo action
742cdf0e10cSrcweir         if( ScDrawLayer* pDrawLayer = mrDoc.GetDrawLayer() )
743*577c0052SWang Lei                 if( pDrawLayer->IsUndoAllowed() )
744cdf0e10cSrcweir                     if( pDrawLayer->IsRecording() )
745cdf0e10cSrcweir                         pDrawLayer->AddCalcUndo( pDrawLayer->GetSdrUndoFactory().CreateUndoNewObject( *maNoteData.mpCaption ) );
746cdf0e10cSrcweir     }
747cdf0e10cSrcweir }
748cdf0e10cSrcweir 
RemoveCaption()749cdf0e10cSrcweir void ScPostIt::RemoveCaption()
750cdf0e10cSrcweir {
751cdf0e10cSrcweir 
752cdf0e10cSrcweir     /*  Remove caption object only, if this note is its owner (e.g. notes in
753cdf0e10cSrcweir         undo documents refer to captions in original document, do not remove
754cdf0e10cSrcweir         them from drawing layer here). */
755cdf0e10cSrcweir     ScDrawLayer* pDrawLayer = mrDoc.GetDrawLayer();
756cdf0e10cSrcweir     if( maNoteData.mpCaption && (pDrawLayer == maNoteData.mpCaption->GetModel()) )
757cdf0e10cSrcweir     {
758cdf0e10cSrcweir         OSL_ENSURE( pDrawLayer, "ScPostIt::RemoveCaption - object without drawing layer" );
759cdf0e10cSrcweir         SdrPage* pDrawPage = maNoteData.mpCaption->GetPage();
760cdf0e10cSrcweir         OSL_ENSURE( pDrawPage, "ScPostIt::RemoveCaption - object without drawing page" );
761cdf0e10cSrcweir         if( pDrawPage )
762cdf0e10cSrcweir         {
763cdf0e10cSrcweir             pDrawPage->RecalcObjOrdNums();
764cdf0e10cSrcweir             // create drawing undo action (before removing the object to have valid draw page in undo action)
765*577c0052SWang Lei             bool bRecording = ( pDrawLayer && pDrawLayer->IsUndoAllowed() && pDrawLayer->IsRecording() );
766cdf0e10cSrcweir             if( bRecording )
767cdf0e10cSrcweir                 pDrawLayer->AddCalcUndo( pDrawLayer->GetSdrUndoFactory().CreateUndoDeleteObject( *maNoteData.mpCaption ) );
768cdf0e10cSrcweir             // remove the object from the drawing page, delete if undo is disabled
769cdf0e10cSrcweir             SdrObject* pObj = pDrawPage->RemoveObject( maNoteData.mpCaption->GetOrdNum() );
770cdf0e10cSrcweir             if( !bRecording )
771cdf0e10cSrcweir                 SdrObject::Free( pObj );
772cdf0e10cSrcweir         }
773cdf0e10cSrcweir     }
774cdf0e10cSrcweir     maNoteData.mpCaption = 0;
775cdf0e10cSrcweir }
776cdf0e10cSrcweir 
777cdf0e10cSrcweir // ============================================================================
778cdf0e10cSrcweir 
UpdateCaptionPositions(ScDocument & rDoc,const ScRange & rRange)779cdf0e10cSrcweir void ScNoteUtil::UpdateCaptionPositions( ScDocument& rDoc, const ScRange& rRange )
780cdf0e10cSrcweir {
781cdf0e10cSrcweir     // do not use ScCellIterator, it skips filtered and subtotal cells
782cdf0e10cSrcweir     for( ScAddress aPos( rRange.aStart ); aPos.Tab() <= rRange.aEnd.Tab(); aPos.IncTab() )
783cdf0e10cSrcweir         for( aPos.SetCol( rRange.aStart.Col() ); aPos.Col() <= rRange.aEnd.Col(); aPos.IncCol() )
784cdf0e10cSrcweir             for( aPos.SetRow( rRange.aStart.Row() ); aPos.Row() <= rRange.aEnd.Row(); aPos.IncRow() )
785cdf0e10cSrcweir                 if( ScPostIt* pNote = rDoc.GetNote( aPos ) )
786cdf0e10cSrcweir                     pNote->UpdateCaptionPos( aPos );
787cdf0e10cSrcweir }
788cdf0e10cSrcweir 
CreateTempCaption(ScDocument & rDoc,const ScAddress & rPos,SdrPage & rDrawPage,const OUString & rUserText,const Rectangle & rVisRect,bool bTailFront)789cdf0e10cSrcweir SdrCaptionObj* ScNoteUtil::CreateTempCaption(
790cdf0e10cSrcweir         ScDocument& rDoc, const ScAddress& rPos, SdrPage& rDrawPage,
791cdf0e10cSrcweir         const OUString& rUserText, const Rectangle& rVisRect, bool bTailFront )
792cdf0e10cSrcweir {
793cdf0e10cSrcweir     OUStringBuffer aBuffer( rUserText );
794cdf0e10cSrcweir     // add plain text of invisible (!) cell note (no formatting etc.)
795cdf0e10cSrcweir     SdrCaptionObj* pNoteCaption = 0;
796cdf0e10cSrcweir     const ScPostIt* pNote = rDoc.GetNote( rPos );
797cdf0e10cSrcweir     if( pNote && !pNote->IsCaptionShown() )
798cdf0e10cSrcweir     {
799cdf0e10cSrcweir         if( aBuffer.getLength() > 0 )
800cdf0e10cSrcweir             aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( "\n--------\n" ) ).append( pNote->GetText() );
801cdf0e10cSrcweir         pNoteCaption = pNote->GetOrCreateCaption( rPos );
802cdf0e10cSrcweir     }
803cdf0e10cSrcweir 
804cdf0e10cSrcweir     // create a caption if any text exists
805cdf0e10cSrcweir     if( !pNoteCaption && (aBuffer.getLength() == 0) )
806cdf0e10cSrcweir         return 0;
807cdf0e10cSrcweir 
808cdf0e10cSrcweir     // prepare visible rectangle (add default distance to all borders)
809cdf0e10cSrcweir     Rectangle aVisRect(
810cdf0e10cSrcweir         rVisRect.Left() + SC_NOTECAPTION_BORDERDIST_TEMP,
811cdf0e10cSrcweir         rVisRect.Top() + SC_NOTECAPTION_BORDERDIST_TEMP,
812cdf0e10cSrcweir         rVisRect.Right() - SC_NOTECAPTION_BORDERDIST_TEMP,
813cdf0e10cSrcweir         rVisRect.Bottom() - SC_NOTECAPTION_BORDERDIST_TEMP );
814cdf0e10cSrcweir 
815cdf0e10cSrcweir     // create the caption object
816cdf0e10cSrcweir     ScCaptionCreator aCreator( rDoc, rPos, true, bTailFront );
817cdf0e10cSrcweir     SdrCaptionObj* pCaption = aCreator.GetCaption();
818cdf0e10cSrcweir 
819cdf0e10cSrcweir     // insert caption into page (needed to set caption text)
820cdf0e10cSrcweir     rDrawPage.InsertObject( pCaption );
821cdf0e10cSrcweir 
822cdf0e10cSrcweir     // clone the edit text object, unless user text is present, then set this text
823cdf0e10cSrcweir     if( pNoteCaption && (rUserText.getLength() == 0) )
824cdf0e10cSrcweir     {
825cdf0e10cSrcweir         if( OutlinerParaObject* pOPO = pNoteCaption->GetOutlinerParaObject() )
826cdf0e10cSrcweir             pCaption->SetOutlinerParaObject( new OutlinerParaObject( *pOPO ) );
827cdf0e10cSrcweir         // set formatting (must be done after setting text) and resize the box to fit the text
828cdf0e10cSrcweir         pCaption->SetMergedItemSetAndBroadcast( pNoteCaption->GetMergedItemSet() );
829cdf0e10cSrcweir         Rectangle aCaptRect( pCaption->GetLogicRect().TopLeft(), pNoteCaption->GetLogicRect().GetSize() );
830cdf0e10cSrcweir         pCaption->SetLogicRect( aCaptRect );
831cdf0e10cSrcweir     }
832cdf0e10cSrcweir     else
833cdf0e10cSrcweir     {
834cdf0e10cSrcweir         // if pNoteCaption is null, then aBuffer contains some text
835cdf0e10cSrcweir         pCaption->SetText( aBuffer.makeStringAndClear() );
836cdf0e10cSrcweir         ScCaptionUtil::SetDefaultItems( *pCaption, rDoc );
837cdf0e10cSrcweir         // adjust caption size to text size
838cdf0e10cSrcweir         long nMaxWidth = ::std::min< long >( aVisRect.GetWidth() * 2 / 3, SC_NOTECAPTION_MAXWIDTH_TEMP );
839cdf0e10cSrcweir         pCaption->SetMergedItem( SdrTextAutoGrowWidthItem( sal_True ) );
840cdf0e10cSrcweir         pCaption->SetMergedItem( SdrTextMinFrameWidthItem( SC_NOTECAPTION_WIDTH ) );
841cdf0e10cSrcweir         pCaption->SetMergedItem( SdrTextMaxFrameWidthItem( nMaxWidth ) );
842cdf0e10cSrcweir         pCaption->SetMergedItem( SdrTextAutoGrowHeightItem( sal_True ) );
843cdf0e10cSrcweir         pCaption->AdjustTextFrameWidthAndHeight();
844cdf0e10cSrcweir     }
845cdf0e10cSrcweir 
846cdf0e10cSrcweir     // move caption into visible area
847cdf0e10cSrcweir     aCreator.AutoPlaceCaption( &aVisRect );
848cdf0e10cSrcweir     return pCaption;
849cdf0e10cSrcweir }
850cdf0e10cSrcweir 
CreateNoteFromCaption(ScDocument & rDoc,const ScAddress & rPos,SdrCaptionObj & rCaption,bool bShown)851cdf0e10cSrcweir ScPostIt* ScNoteUtil::CreateNoteFromCaption(
852cdf0e10cSrcweir         ScDocument& rDoc, const ScAddress& rPos, SdrCaptionObj& rCaption, bool bShown )
853cdf0e10cSrcweir {
854cdf0e10cSrcweir     ScNoteData aNoteData( bShown );
855cdf0e10cSrcweir     aNoteData.mpCaption = &rCaption;
856cdf0e10cSrcweir     ScPostIt* pNote = new ScPostIt( rDoc, rPos, aNoteData, false );
857cdf0e10cSrcweir     pNote->AutoStamp();
858cdf0e10cSrcweir     rDoc.TakeNote( rPos, pNote );
859cdf0e10cSrcweir     // if pNote still points to the note after TakeNote(), insertion was successful
860cdf0e10cSrcweir     if( pNote )
861cdf0e10cSrcweir     {
862cdf0e10cSrcweir         // ScNoteCaptionCreator c'tor updates the caption object to be part of a note
863cdf0e10cSrcweir         ScNoteCaptionCreator aCreator( rDoc, rPos, rCaption, bShown );
864cdf0e10cSrcweir     }
865cdf0e10cSrcweir     return pNote;
866cdf0e10cSrcweir }
867cdf0e10cSrcweir 
CreateNoteFromObjectData(ScDocument & rDoc,const ScAddress & rPos,SfxItemSet * pItemSet,OutlinerParaObject * pOutlinerObj,const Rectangle & rCaptionRect,bool bShown,bool bAlwaysCreateCaption)868cdf0e10cSrcweir ScPostIt* ScNoteUtil::CreateNoteFromObjectData(
869cdf0e10cSrcweir         ScDocument& rDoc, const ScAddress& rPos, SfxItemSet* pItemSet,
870cdf0e10cSrcweir         OutlinerParaObject* pOutlinerObj, const Rectangle& rCaptionRect,
871cdf0e10cSrcweir         bool bShown, bool bAlwaysCreateCaption )
872cdf0e10cSrcweir {
873cdf0e10cSrcweir     OSL_ENSURE( pItemSet && pOutlinerObj, "ScNoteUtil::CreateNoteFromObjectData - item set and outliner object expected" );
874cdf0e10cSrcweir     ScNoteData aNoteData( bShown );
875cdf0e10cSrcweir     aNoteData.mxInitData.reset( new ScCaptionInitData );
876cdf0e10cSrcweir     ScCaptionInitData& rInitData = *aNoteData.mxInitData;
877cdf0e10cSrcweir     rInitData.mxItemSet.reset( pItemSet );
878cdf0e10cSrcweir     rInitData.mxOutlinerObj.reset( pOutlinerObj );
879cdf0e10cSrcweir 
880cdf0e10cSrcweir     // convert absolute caption position to relative position
881cdf0e10cSrcweir     rInitData.mbDefaultPosSize = rCaptionRect.IsEmpty();
882cdf0e10cSrcweir     if( !rInitData.mbDefaultPosSize )
883cdf0e10cSrcweir     {
884cdf0e10cSrcweir         Rectangle aCellRect = ScDrawLayer::GetCellRect( rDoc, rPos, true );
885cdf0e10cSrcweir         bool bNegPage = rDoc.IsNegativePage( rPos.Tab() );
886cdf0e10cSrcweir         rInitData.maCaptionOffset.X() = bNegPage ? (aCellRect.Left() - rCaptionRect.Right()) : (rCaptionRect.Left() - aCellRect.Right());
887cdf0e10cSrcweir         rInitData.maCaptionOffset.Y() = rCaptionRect.Top() - aCellRect.Top();
888cdf0e10cSrcweir         rInitData.maCaptionSize = rCaptionRect.GetSize();
889cdf0e10cSrcweir     }
890cdf0e10cSrcweir 
891cdf0e10cSrcweir     /*  Create the note and insert it into the document. If the note is
892cdf0e10cSrcweir         visible, the caption object will be created automatically. */
893cdf0e10cSrcweir     ScPostIt* pNote = new ScPostIt( rDoc, rPos, aNoteData, bAlwaysCreateCaption );
894cdf0e10cSrcweir     pNote->AutoStamp();
895cdf0e10cSrcweir     rDoc.TakeNote( rPos, pNote );
896cdf0e10cSrcweir     // if pNote still points to the note after TakeNote(), insertion was successful
897cdf0e10cSrcweir     return pNote;
898cdf0e10cSrcweir }
899cdf0e10cSrcweir 
CreateNoteFromString(ScDocument & rDoc,const ScAddress & rPos,const OUString & rNoteText,bool bShown,bool bAlwaysCreateCaption)900cdf0e10cSrcweir ScPostIt* ScNoteUtil::CreateNoteFromString(
901cdf0e10cSrcweir         ScDocument& rDoc, const ScAddress& rPos, const OUString& rNoteText,
902cdf0e10cSrcweir         bool bShown, bool bAlwaysCreateCaption )
903cdf0e10cSrcweir {
904cdf0e10cSrcweir     ScPostIt* pNote = 0;
905cdf0e10cSrcweir     if( rNoteText.getLength() > 0 )
906cdf0e10cSrcweir     {
907cdf0e10cSrcweir         ScNoteData aNoteData( bShown );
908cdf0e10cSrcweir         aNoteData.mxInitData.reset( new ScCaptionInitData );
909cdf0e10cSrcweir         ScCaptionInitData& rInitData = *aNoteData.mxInitData;
910cdf0e10cSrcweir         rInitData.maSimpleText = rNoteText;
911cdf0e10cSrcweir         rInitData.mbDefaultPosSize = true;
912cdf0e10cSrcweir 
913cdf0e10cSrcweir         /*  Create the note and insert it into the document. If the note is
914cdf0e10cSrcweir             visible, the caption object will be created automatically. */
915cdf0e10cSrcweir         pNote = new ScPostIt( rDoc, rPos, aNoteData, bAlwaysCreateCaption );
916cdf0e10cSrcweir         pNote->AutoStamp();
917cdf0e10cSrcweir         rDoc.TakeNote( rPos, pNote );
918cdf0e10cSrcweir         // if pNote still points to the note after TakeNote(), insertion was successful
919cdf0e10cSrcweir     }
920cdf0e10cSrcweir     return pNote;
921cdf0e10cSrcweir }
922cdf0e10cSrcweir 
923cdf0e10cSrcweir // ============================================================================
924