23#include <rtl/ustrbuf.hxx>
31#include <osl/diagnose.h>
48#include <document.hxx>
62const tools::Long SC_NOTECAPTION_MAXWIDTH_TEMP = 12000;
67const tools::Long SC_NOTECAPTION_BORDERDIST_TEMP = 100;
74 static void SetCaptionLayer(
SdrCaptionObj& rCaption,
bool bShown );
76 static void SetBasicCaptionSettings(
SdrCaptionObj& rCaption,
bool bShown );
83void ScCaptionUtil::SetCaptionLayer(
SdrCaptionObj& rCaption,
bool bShown )
90void ScCaptionUtil::SetBasicCaptionSettings(
SdrCaptionObj& rCaption,
bool bShown )
92 SetCaptionLayer( rCaption, bShown );
101 OSL_ENSURE( pObjData,
"ScCaptionUtil::SetCaptionUserData - missing drawing object user data" );
149 aItemSet.
Put(*pExtraItemSet);
164class ScCaptionCreator
182 void UpdateCaptionPos();
189 Point CalcTailPos(
bool bTailFront );
191 void CreateCaption(
bool bShown,
bool bTailFront );
208ScCaptionCreator::ScCaptionCreator(
ScDocument& rDoc,
const ScAddress& rPos,
bool bTailFront ) :
213 CreateCaption(
true, bTailFront );
219 mxCaption( xCaption )
231SdrPage* ScCaptionCreator::GetDrawPage()
234 return pDrawLayer ? pDrawLayer->
GetPage(
static_cast< sal_uInt16
>( maPos.Tab() ) ) :
nullptr;
242 Point aTailPos = mxCaption->GetTailPos();
243 aTailPos.setX( ::std::clamp( aTailPos.X(), rVisRect.
Left(), rVisRect.
Right() ) );
244 aTailPos.setY( ::std::clamp( aTailPos.Y(), rVisRect.
Top(), rVisRect.
Bottom() ) );
245 mxCaption->SetTailPos( aTailPos );
251 aCaptPos.setX( ::std::min< tools::Long >( aCaptPos.X(), rVisRect.
Right() - aCaptRect.
GetWidth() ) );
253 aCaptPos.setX( ::std::max< tools::Long >( aCaptPos.X(), rVisRect.
Left() ) );
255 aCaptPos.setY( ::std::min< tools::Long >( aCaptPos.Y(), rVisRect.
Bottom() - aCaptRect.
GetHeight() ) );
257 aCaptPos.setY( ::std::max< tools::Long >( aCaptPos.Y(), rVisRect.
Top() ) );
259 aCaptRect.
SetPos( aCaptPos );
260 mxCaption->SetLogicRect( aCaptRect );
279 tools::Long nNeededSpaceX = nWidth + SC_NOTECAPTION_CELLDIST;
280 tools::Long nNeededSpaceY = nHeight + SC_NOTECAPTION_CELLDIST;
283 bool bFitsWidthLeft = nNeededSpaceX <= nLeftSpace;
284 bool bFitsWidthRight = nNeededSpaceX <= nRightSpace;
285 bool bFitsWidth = nWidth <= rVisRect.
GetWidth();
288 bool bFitsHeightTop = nNeededSpaceY <= nTopSpace;
289 bool bFitsHeightBottom = nNeededSpaceY <= nBottomSpace;
290 bool bFitsHeight = nHeight <= rVisRect.
GetHeight();
293 bool bFitsLeft = bFitsWidthLeft && bFitsHeight;
294 bool bFitsRight = bFitsWidthRight && bFitsHeight;
295 bool bFitsTop = bFitsWidth && bFitsHeightTop;
296 bool bFitsBottom = bFitsWidth && bFitsHeightBottom;
300 if( bFitsLeft || bFitsRight || (!bFitsTop && !bFitsBottom) )
303 bool bPreferLeft = bFitsLeft && (mbNegPage || !bFitsRight);
304 bool bPreferRight = bFitsRight && (!mbNegPage || !bFitsLeft);
306 if( bPreferLeft || (!bPreferRight && (nLeftSpace > nRightSpace)) )
307 aCaptPos.setX( maCellRect.Left() - SC_NOTECAPTION_CELLDIST - nWidth );
309 aCaptPos.setX( maCellRect.Right() + SC_NOTECAPTION_CELLDIST );
311 aCaptPos.setY( maCellRect.Top() + SC_NOTECAPTION_OFFSET_Y );
316 aCaptPos.setX( maCellRect.Left() + SC_NOTECAPTION_OFFSET_X );
319 aCaptPos.setY( maCellRect.Top() - SC_NOTECAPTION_CELLDIST - nHeight );
321 aCaptPos.setY( maCellRect.Bottom() + SC_NOTECAPTION_CELLDIST );
325 aCaptRect.
SetPos( aCaptPos );
326 mxCaption->SetLogicRect( aCaptRect );
327 FitCaptionToRect( pVisRect );
330void ScCaptionCreator::UpdateCaptionPos()
335 const Point& rOldTailPos = mxCaption->GetTailPos();
336 Point aTailPos = CalcTailPos(
false );
337 if( rOldTailPos != aTailPos )
341 pDrawLayer->
AddCalcUndo( std::make_unique<SdrUndoGeoObj>( *mxCaption ) );
344 tools::Long nDiffX = (rOldTailPos.X() >= 0) ? (aCaptRect.
Left() - rOldTailPos.X()) : (rOldTailPos.X() - aCaptRect.
Right());
345 if( mbNegPage ) nDiffX = -nDiffX - aCaptRect.
GetWidth();
347 aCaptRect.
SetPos( aTailPos +
Point( nDiffX, nDiffY ) );
349 mxCaption->SetTailPos( aTailPos );
350 mxCaption->SetLogicRect( aCaptRect );
357 if( pCaptData && (maPos != pCaptData->
maStart) )
361 pDrawLayer->
AddCalcUndo( std::make_unique<ScUndoObjData>( mxCaption.get(), pCaptData->
maStart, pCaptData->
maEnd, maPos, pCaptData->
maEnd ) );
367Point ScCaptionCreator::CalcTailPos(
bool bTailFront )
370 bool bTailLeft = bTailFront != mbNegPage;
371 Point aTailPos = bTailLeft ? maCellRect.TopLeft() : maCellRect.TopRight();
373 if( bTailLeft ) aTailPos.AdjustX(10 );
else aTailPos.AdjustX( -10 );
374 aTailPos.AdjustY(10);
378void ScCaptionCreator::CreateCaption(
bool bShown,
bool bTailFront )
382 Point aTailPos = CalcTailPos( bTailFront );
385 *mrDoc.GetDrawLayer(),
389 ScCaptionUtil::SetBasicCaptionSettings( *mxCaption, bShown );
392void ScCaptionCreator::Initialize()
395 mbNegPage = mrDoc.IsNegativePage( maPos.Tab() );
396 if(
SdrPage* pDrawPage = GetDrawPage() )
402 maPageRect.Normalize();
407class ScNoteCaptionCreator :
public ScCaptionCreator
417 ScCaptionCreator( rDoc, rPos )
419 SdrPage* pDrawPage = GetDrawPage();
420 OSL_ENSURE( pDrawPage,
"ScNoteCaptionCreator::ScNoteCaptionCreator - no drawing page" );
425 CreateCaption( rNoteData.
mbShown,
false );
427 OSL_ENSURE( rNoteData.
mxCaption,
"ScNoteCaptionCreator::ScNoteCaptionCreator - missing caption object" );
431 ScCaptionUtil::SetCaptionUserData( *rNoteData.
mxCaption, rPos );
438 ScCaptionCreator( rDoc, rPos, xCaption )
440 SdrPage* pDrawPage = GetDrawPage();
441 OSL_ENSURE( pDrawPage,
"ScNoteCaptionCreator::ScNoteCaptionCreator - no drawing page" );
442 OSL_ENSURE( xCaption->getSdrPageFromSdrObject() == pDrawPage,
"ScNoteCaptionCreator::ScNoteCaptionCreator - wrong drawing page in caption" );
443 if( pDrawPage && (xCaption->getSdrPageFromSdrObject() == pDrawPage) )
446 ScCaptionUtil::SetCaptionUserData( *xCaption, rPos );
448 ScCaptionUtil::SetBasicCaptionSettings( *xCaption, bShown );
450 xCaption->SetTailPos( CalcTailPos(
false ) );
470 mbDefaultPosSize( true )
492 maNoteData( rNote.maNoteData )
501 maNoteData(
std::move( aNoteData ))
517 return bCloneCaption ? std::make_unique<ScPostIt>( rDestDoc, rDestPos, *
this, nPostItId ) : std::make_unique<ScPostIt>( rDestDoc, rDestPos,
maNoteData,
false,
mnPostItId );
559 for( sal_Int32 nPara = 0; nPara < nParaCount; ++nPara )
565 return aBuffer.makeStringAndClear();
575 return pEditObj->GetParagraphCount() > 1;
644 aCreator.UpdateCaptionPos();
667 "ScPostIt::CreateCaptionFromInitData - note caption should not be created in undo/clip documents" );
690 OSL_ENSURE( xInitData->mxOutlinerObj || !xInitData->maSimpleText.isEmpty(),
691 "ScPostIt::CreateCaptionFromInitData - need either outliner para object or simple text" );
692 if (xInitData->mxOutlinerObj)
698 ScCaptionUtil::SetDefaultItems( *
maNoteData.
mxCaption,
mrDoc, xInitData->moItemSet ? &*xInitData->moItemSet :
nullptr );
701 if( xInitData->mbDefaultPosSize )
707 aCreator.AutoPlaceCaption();
713 tools::Long nPosX = bNegPage ? (aCellRect.
Left() - xInitData->maCaptionOffset.X()) : (aCellRect.
Right() + xInitData->maCaptionOffset.X());
714 tools::Long nPosY = aCellRect.
Top() + xInitData->maCaptionOffset.Y();
717 aCreator.FitCaptionToRect();
727 OSL_ENSURE( !
maNoteData.
mxCaption,
"ScPostIt::CreateCaption - unexpected caption object found" );
732 OSL_ENSURE( !
mrDoc.
IsUndo(),
"ScPostIt::CreateCaption - note caption should not be created in undo documents" );
756 aCaptRect.
Move( aDist.X(), aDist.Y() );
758 aCreator.FitCaptionToRect();
764 aCreator.AutoPlaceCaption();
786 SAL_WARN_IF( !pDrawPage,
"sc.core",
"ScCaptionPtr::removeFromDrawPageAndFree - object without drawing page");
791 bool bRecording = (pDrawLayer && pDrawLayer->
IsRecording());
800 SAL_INFO(
"sc.core",
"ScPostIt::RemoveCaption -"
807 SAL_INFO(
"sc.core",
"ScPostIt::RemoveCaption - forgetting one ref");
814 std::u16string_view rUserText,
const tools::Rectangle& rVisRect,
bool bTailFront )
816 OUStringBuffer
aBuffer( rUserText );
828 if( !pNoteCaption &&
aBuffer.isEmpty() )
833 rVisRect.
Left() + SC_NOTECAPTION_BORDERDIST_TEMP,
834 rVisRect.
Top() + SC_NOTECAPTION_BORDERDIST_TEMP,
835 rVisRect.
Right() - SC_NOTECAPTION_BORDERDIST_TEMP,
836 rVisRect.
Bottom() - SC_NOTECAPTION_BORDERDIST_TEMP );
839 ScCaptionCreator aCreator( rDoc, rPos, bTailFront );
847 if( pNoteCaption && rUserText.empty() )
850 pCaption->SetOutlinerParaObject( *pOPO );
854 pCaption->SetLogicRect( aCaptRect );
859 pCaption->SetText(
aBuffer.makeStringAndClear() );
860 ScCaptionUtil::SetDefaultItems( *pCaption, rDoc,
nullptr );
862 tools::Long nMaxWidth = ::std::min< tools::Long >( aVisRect.
GetWidth() * 2 / 3, SC_NOTECAPTION_MAXWIDTH_TEMP );
867 pCaption->AdjustTextFrameWidthAndHeight();
871 aCreator.AutoPlaceCaption( &aVisRect );
874 return aCreator.GetCaption();
885 rDoc.
SetNote(rPos, std::unique_ptr<ScPostIt>(pNote));
888 ScNoteCaptionCreator aCreator( rDoc, rPos, aNoteData.
mxCaption,
true );
899 aNoteData.
mxInitData = std::make_shared<ScCaptionInitData>();
901 rInitData.
moItemSet.emplace(std::move(rItemSet));
917 ScPostIt* pNote =
new ScPostIt( rDoc, rPos, std::move(aNoteData),
false, 0 );
920 rDoc.
SetNote(rPos, std::unique_ptr<ScPostIt>(pNote));
927 bool bShown,
bool bAlwaysCreateCaption, sal_uInt32 nPostItId )
930 if( !rNoteText.isEmpty() )
933 aNoteData.
mxInitData = std::make_shared<ScCaptionInitData>();
940 pNote =
new ScPostIt( rDoc, rPos, std::move(aNoteData), bAlwaysCreateCaption, nPostItId );
943 rDoc.
SetNote(rPos, std::unique_ptr<ScPostIt>(pNote));
951 maPos(rPos), mpNote(pNote) {}
OUString GetText(LineEnd eEnd=LINEEND_LF) const
sal_Int32 GetParagraphCount() const
OUString getDate(const Date &rDate) const
const EditTextObject & GetTextObject() const
static Color GetCommentColor()
void SetNote(const ScAddress &rPos, std::unique_ptr< ScPostIt > pNote)
SC_DLLPUBLIC void InitDrawLayer(SfxObjectShell *pDocShell=nullptr)
SC_DLLPUBLIC ScDocumentPool * GetPool()
SC_DLLPUBLIC ScPostIt * GetNote(const ScAddress &rPos)
SC_DLLPUBLIC bool IsNegativePage(SCTAB nTab) const
SC_DLLPUBLIC ScDrawLayer * GetDrawLayer()
SC_DLLPUBLIC ScNoteEditEngine & GetNoteEngine()
bool IsInDtorClear() const
static tools::Rectangle GetCellRect(const ScDocument &rDoc, const ScAddress &rPos, bool bMergedCell)
Returns the rectangle for the passed cell address in 1/100 mm.
static ScDrawObjData * GetObjData(SdrObject *pObj, bool bCreate=false)
static ScDrawObjData * GetNoteCaptionData(SdrObject *pObj, SCTAB nTab)
Returns the object data, if the passed object is a cell note caption.
void AddCalcUndo(std::unique_ptr< SdrUndoAction > pUndo)
void SetTextCurrentDefaults(const EditTextObject &rTextObject)
SetText and apply defaults already set.
static SC_DLLPUBLIC const LocaleDataWrapper & getLocaleData()
static ScPostIt * CreateNoteFromObjectData(ScDocument &rDoc, const ScAddress &rPos, SfxItemSet &&oItemSet, const OutlinerParaObject &rOutlinerObj, const tools::Rectangle &rCaptionRect, bool bShown)
Creates a cell note based on the passed caption object data.
static ScPostIt * CreateNoteFromCaption(ScDocument &rDoc, const ScAddress &rPos, SdrCaptionObj *pCaption)
Creates a cell note using the passed caption drawing object.
static ScPostIt * CreateNoteFromString(ScDocument &rDoc, const ScAddress &rPos, const OUString &rNoteText, bool bShown, bool bAlwaysCreateCaption, sal_uInt32 nPostItId=0)
Creates a cell note based on the passed string and inserts it into the document.
static rtl::Reference< SdrCaptionObj > CreateTempCaption(ScDocument &rDoc, const ScAddress &rPos, SdrPage &rDrawPage, std::u16string_view rUserText, const tools::Rectangle &rVisRect, bool bTailFront)
Creates and returns a caption object for a temporary caption.
void FillEditItemSet(SfxItemSet *pEditSet, const SfxItemSet *pCondSet=nullptr) const
Converts all Calc items contained in the own item set to edit engine items and puts them into pEditSe...
Additional class containing cell annotation data.
void SetAuthor(const OUString &rAuthor)
Sets a new author date for this note.
void ShowCaptionTemp(const ScAddress &rPos, bool bShow=true)
Shows or hides the caption temporarily (does not change internal visibility state).
~ScPostIt()
Removes the caption object from drawing layer, if this note is its owner.
ScNoteData maNoteData
Parent document containing the note.
void AutoStamp()
Sets date and author from system settings.
void SetText(const ScAddress &rPos, const OUString &rText)
Changes the caption text of this note.
void UpdateCaptionPos(const ScAddress &rPos)
Updates caption position according to position of the passed cell.
static sal_uInt32 mnLastPostItId
std::unique_ptr< ScPostIt > Clone(const ScAddress &rOwnPos, ScDocument &rDestDoc, const ScAddress &rDestPos, bool bCloneCaption) const
Clones this note and its caption object, if specified.
sal_uInt32 mnPostItId
Note data with pointer to caption object.
void ShowCaption(const ScAddress &rPos, bool bShow)
Shows or hides the note caption object.
const EditTextObject * GetEditTextObject() const
Returns the pointer to the current edit text object, or null.
SdrCaptionObj * GetOrCreateCaption(const ScAddress &rPos) const
Returns the caption object of this note.
void CreateCaptionFromInitData(const ScAddress &rPos) const
Creates the caption object from initial caption data if existing.
void ForgetCaption(bool bPreserveData=false)
Forgets the pointer to the note caption object.
ScPostIt(ScDocument &rDoc, const ScAddress &rPos, sal_uInt32 nPostItId=0)
Creates an empty note and its caption object and places it according to the passed cell position.
void SetDate(const OUString &rDate)
Sets a new creation date for this note.
const OutlinerParaObject * GetOutlinerObject() const
Returns the pointer to the current outliner object, or null.
bool IsCaptionShown() const
Returns true, if the caption object is visible.
OUString GetText() const
Returns the caption text of this note.
void RemoveCaption()
Removes the caption object from the drawing layer, if this note is its owner.
bool HasMultiLineText() const
Returns true, if the caption text of this note contains line breaks.
void CreateCaption(const ScAddress &rPos, const SdrCaptionObj *pCaption=nullptr)
Creates a new caption object at the passed cell position, clones passed existing caption.
void SetSpecialTextBoxShadow()
const Point & GetTailPos() const
virtual const tools::Rectangle & GetLogicRect() const override
const SdrPage * GetPage(sal_uInt16 nPgNum) const
virtual void InsertObject(SdrObject *pObj, size_t nPos=SAL_MAX_SIZE)
virtual rtl::Reference< SdrObject > RemoveObject(size_t nObjNum)
void SetMergedItemSet(const SfxItemSet &rSet, bool bClearAllItems=false)
const SfxItemSet & GetMergedItemSet() const
virtual SdrLayerID GetLayer() const
virtual void SetLayer(SdrLayerID nLayer)
virtual OutlinerParaObject * GetOutlinerParaObject() const override
const SfxPoolItem & GetDefaultItem(sal_uInt16 nWhich) const
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
void append(const basegfx::B2DPoint &rPoint, sal_uInt32 nCount)
void setClosed(bool bNew)
constexpr SdrLayerID SC_LAYER_HIDDEN(4)
constexpr SdrLayerID SC_LAYER_INTERN(2)
#define SAL_WARN_IF(condition, area, stream)
#define SAL_INFO(area, stream)
CAUTION! The following defines must be in the same namespace as the respective type.
constexpr TypedWhichId< ScPatternAttr > ATTR_PATTERN(156)
SdrOnOffItem makeSdrShadowItem(bool bShadow)
SdrMetricItem makeSdrShadowXDistItem(tools::Long nDist)
SdrMetricItem makeSdrShadowYDistItem(tools::Long nDist)
SdrOnOffItem makeSdrTextAutoGrowHeightItem(bool bAuto)
SdrOnOffItem makeSdrTextAutoGrowWidthItem(bool bAuto)
SdrMetricItem makeSdrTextUpperDistItem(tools::Long mnHeight)
SdrMetricItem makeSdrTextRightDistItem(tools::Long mnHeight)
SdrMetricItem makeSdrTextLowerDistItem(tools::Long mnHeight)
SdrMetricItem makeSdrTextLeftDistItem(tools::Long mnHeight)
SdrMetricItem makeSdrTextMaxFrameWidthItem(tools::Long mnWidth)
SdrMetricItem makeSdrTextMinFrameWidthItem(tools::Long mnWidth)
Point maCaptionOffset
Simple text without formatting.
Size maCaptionSize
Caption position relative to cell corner.
OUString maSimpleText
Text object with all text portion formatting.
bool mbDefaultPosSize
Size of the caption object.
std::optional< OutlinerParaObject > mxOutlinerObj
Caption object formatting.
ScCaptionInitData()
True = use default position and size for caption.
std::optional< SfxItemSet > moItemSet
Internal data for a cell annotation.
rtl::Reference< SdrCaptionObj > mxCaption
Initial data for invisible notes without SdrObject.
ScCaptionInitDataRef mxInitData
Author of the note.
OUString maAuthor
Creation date of the note.
bool mbShown
Drawing object representing the cell note.
ScNoteData(bool bShown=false)
True = note is visible.
NoteEntry(const ScAddress &rPos, const ScPostIt *pNote)
std::unique_ptr< char[]> aBuffer