23#include <rtl/ustrbuf.hxx>
31#include <osl/diagnose.h>
48#include <document.hxx>
62#include <com/sun/star/text/XText.hpp>
63#include <com/sun/star/text/XTextAppend.hpp>
64#include <com/sun/star/beans/XPropertySet.hpp>
65#include <com/sun/star/awt/FontWeight.hpp>
73const tools::Long SC_NOTECAPTION_MAXWIDTH_TEMP = 12000;
78const tools::Long SC_NOTECAPTION_BORDERDIST_TEMP = 100;
85 static void SetCaptionLayer(
SdrCaptionObj& rCaption,
bool bShown );
87 static void SetBasicCaptionSettings(
SdrCaptionObj& rCaption,
bool bShown );
94void ScCaptionUtil::SetCaptionLayer(
SdrCaptionObj& rCaption,
bool bShown )
101void ScCaptionUtil::SetBasicCaptionSettings(
SdrCaptionObj& rCaption,
bool bShown )
105 SetCaptionLayer( rCaption, bShown );
112 OSL_ENSURE( pObjData,
"ScCaptionUtil::SetCaptionUserData - missing drawing object user data" );
121 aItemSet.
Put(rExtraItemSet);
134class ScCaptionCreator
152 void UpdateCaptionPos();
159 Point CalcTailPos(
bool bTailFront );
161 void CreateCaption(
bool bShown,
bool bTailFront );
178ScCaptionCreator::ScCaptionCreator(
ScDocument& rDoc,
const ScAddress& rPos,
bool bTailFront ) :
183 CreateCaption(
true, bTailFront );
189 mxCaption( xCaption )
201SdrPage* ScCaptionCreator::GetDrawPage()
204 return pDrawLayer ? pDrawLayer->
GetPage(
static_cast< sal_uInt16
>( maPos.Tab() ) ) :
nullptr;
212 Point aTailPos = mxCaption->GetTailPos();
213 aTailPos.
setX( ::std::clamp( aTailPos.
X(), rVisRect.
Left(), rVisRect.
Right() ) );
214 aTailPos.
setY( ::std::clamp( aTailPos.
Y(), rVisRect.
Top(), rVisRect.
Bottom() ) );
215 mxCaption->SetTailPos( aTailPos );
221 aCaptPos.
setX( ::std::min< tools::Long >( aCaptPos.
X(), rVisRect.
Right() - aCaptRect.
GetWidth() ) );
223 aCaptPos.
setX( ::std::max< tools::Long >( aCaptPos.
X(), rVisRect.
Left() ) );
225 aCaptPos.
setY( ::std::min< tools::Long >( aCaptPos.
Y(), rVisRect.
Bottom() - aCaptRect.
GetHeight() ) );
227 aCaptPos.
setY( ::std::max< tools::Long >( aCaptPos.
Y(), rVisRect.
Top() ) );
229 aCaptRect.
SetPos( aCaptPos );
230 mxCaption->SetLogicRect( aCaptRect );
249 tools::Long nNeededSpaceX = nWidth + SC_NOTECAPTION_CELLDIST;
250 tools::Long nNeededSpaceY = nHeight + SC_NOTECAPTION_CELLDIST;
253 bool bFitsWidthLeft = nNeededSpaceX <= nLeftSpace;
254 bool bFitsWidthRight = nNeededSpaceX <= nRightSpace;
255 bool bFitsWidth = nWidth <= rVisRect.
GetWidth();
258 bool bFitsHeightTop = nNeededSpaceY <= nTopSpace;
259 bool bFitsHeightBottom = nNeededSpaceY <= nBottomSpace;
260 bool bFitsHeight = nHeight <= rVisRect.
GetHeight();
263 bool bFitsLeft = bFitsWidthLeft && bFitsHeight;
264 bool bFitsRight = bFitsWidthRight && bFitsHeight;
265 bool bFitsTop = bFitsWidth && bFitsHeightTop;
266 bool bFitsBottom = bFitsWidth && bFitsHeightBottom;
270 if( bFitsLeft || bFitsRight || (!bFitsTop && !bFitsBottom) )
273 bool bPreferLeft = bFitsLeft && (mbNegPage || !bFitsRight);
274 bool bPreferRight = bFitsRight && (!mbNegPage || !bFitsLeft);
276 if( bPreferLeft || (!bPreferRight && (nLeftSpace > nRightSpace)) )
277 aCaptPos.
setX( maCellRect.Left() - SC_NOTECAPTION_CELLDIST - nWidth );
279 aCaptPos.
setX( maCellRect.Right() + SC_NOTECAPTION_CELLDIST );
281 aCaptPos.
setY( maCellRect.Top() + SC_NOTECAPTION_OFFSET_Y );
286 aCaptPos.
setX( maCellRect.Left() + SC_NOTECAPTION_OFFSET_X );
289 aCaptPos.
setY( maCellRect.Top() - SC_NOTECAPTION_CELLDIST - nHeight );
291 aCaptPos.
setY( maCellRect.Bottom() + SC_NOTECAPTION_CELLDIST );
295 aCaptRect.
SetPos( aCaptPos );
296 mxCaption->SetLogicRect( aCaptRect );
297 FitCaptionToRect( pVisRect );
300void ScCaptionCreator::UpdateCaptionPos()
305 const Point& rOldTailPos = mxCaption->GetTailPos();
306 Point aTailPos = CalcTailPos(
false );
307 if( rOldTailPos != aTailPos )
311 pDrawLayer->
AddCalcUndo( std::make_unique<SdrUndoGeoObj>( *mxCaption ) );
314 tools::Long nDiffX = (rOldTailPos.
X() >= 0) ? (aCaptRect.
Left() - rOldTailPos.
X()) : (rOldTailPos.
X() - aCaptRect.
Right());
315 if( mbNegPage ) nDiffX = -nDiffX - aCaptRect.
GetWidth();
317 aCaptRect.
SetPos( aTailPos +
Point( nDiffX, nDiffY ) );
319 mxCaption->SetTailPos( aTailPos );
320 mxCaption->SetLogicRect( aCaptRect );
327 if( pCaptData && (maPos != pCaptData->
maStart) )
331 pDrawLayer->
AddCalcUndo( std::make_unique<ScUndoObjData>( mxCaption.get(), pCaptData->
maStart, pCaptData->
maEnd, maPos, pCaptData->
maEnd ) );
337Point ScCaptionCreator::CalcTailPos(
bool bTailFront )
340 bool bTailLeft = bTailFront != mbNegPage;
341 Point aTailPos = bTailLeft ? maCellRect.TopLeft() : maCellRect.TopRight();
343 if( bTailLeft ) aTailPos.
AdjustX(10 );
else aTailPos.
AdjustX( -10 );
348void ScCaptionCreator::CreateCaption(
bool bShown,
bool bTailFront )
352 Point aTailPos = CalcTailPos( bTailFront );
355 *mrDoc.GetDrawLayer(),
359 ScCaptionUtil::SetBasicCaptionSettings( *mxCaption, bShown );
362void ScCaptionCreator::Initialize()
365 mbNegPage = mrDoc.IsNegativePage( maPos.Tab() );
366 if(
SdrPage* pDrawPage = GetDrawPage() )
372 maPageRect.Normalize();
377class ScNoteCaptionCreator :
public ScCaptionCreator
387 ScCaptionCreator( rDoc, rPos )
389 SdrPage* pDrawPage = GetDrawPage();
390 OSL_ENSURE( pDrawPage,
"ScNoteCaptionCreator::ScNoteCaptionCreator - no drawing page" );
395 CreateCaption( rNoteData.
mbShown,
false );
397 OSL_ENSURE( rNoteData.
mxCaption,
"ScNoteCaptionCreator::ScNoteCaptionCreator - missing caption object" );
401 ScCaptionUtil::SetCaptionUserData( *rNoteData.
mxCaption, rPos );
408 ScCaptionCreator( rDoc, rPos, xCaption )
410 SdrPage* pDrawPage = GetDrawPage();
411 OSL_ENSURE( pDrawPage,
"ScNoteCaptionCreator::ScNoteCaptionCreator - no drawing page" );
412 OSL_ENSURE( xCaption->getSdrPageFromSdrObject() == pDrawPage,
"ScNoteCaptionCreator::ScNoteCaptionCreator - wrong drawing page in caption" );
413 if( pDrawPage && (xCaption->getSdrPageFromSdrObject() == pDrawPage) )
416 ScCaptionUtil::SetCaptionUserData( *xCaption, rPos );
418 ScCaptionUtil::SetBasicCaptionSettings( *xCaption, bShown );
420 xCaption->SetTailPos( CalcTailPos(
false ) );
441 mbDefaultPosSize( true )
463 maNoteData( rNote.maNoteData )
472 maNoteData(
std::move( aNoteData ))
488 bCloneCaption =
false;
491 return bCloneCaption ? std::make_unique<ScPostIt>( rDestDoc, rDestPos, *
this, nPostItId ) : std::make_unique<ScPostIt>( rDestDoc, rDestPos,
maNoteData,
false,
mnPostItId );
535 for( sal_Int32 nPara = 0; nPara < nParaCount; ++nPara )
541 return aBuffer.makeStringAndClear();
611 aCreator.UpdateCaptionPos();
634 "ScPostIt::CreateCaptionFromInitData - note caption should not be created in undo/clip documents" );
657 OSL_ENSURE( xInitData->mxOutlinerObj || !xInitData->maSimpleText.isEmpty(),
658 "ScPostIt::CreateCaptionFromInitData - need either outliner para object or simple text" );
659 if (xInitData->mxOutlinerObj)
664 if (!xInitData->maStyleName.isEmpty())
669 if (xInitData->moItemSet)
678 if (xInitData->moItemSet)
683 if( xInitData->mbDefaultPosSize )
689 aCreator.AutoPlaceCaption();
695 tools::Long nPosX = bNegPage ? (aCellRect.
Left() - xInitData->maCaptionOffset.X()) : (aCellRect.
Right() + xInitData->maCaptionOffset.X());
696 tools::Long nPosY = aCellRect.
Top() + xInitData->maCaptionOffset.Y();
699 aCreator.FitCaptionToRect();
709 OSL_ENSURE( !
maNoteData.
mxCaption,
"ScPostIt::CreateCaption - unexpected caption object found" );
714 OSL_ENSURE( !
mrDoc.
IsUndo(),
"ScPostIt::CreateCaption - note caption should not be created in undo documents" );
737 pPool->
CopyStyleFrom(pStyleSheet->GetPool(), pStyleSheet->GetName(), pStyleSheet->GetFamily(),
true);
739 if (
auto pDestStyleSheet = pPool->Find(pStyleSheet->GetName(), pStyleSheet->GetFamily()))
746 aCaptRect.
Move( aDist.
X(), aDist.
Y() );
748 aCreator.FitCaptionToRect();
757 aCaptRect.
SetSize({ SC_NOTECAPTION_WIDTH, SC_NOTECAPTION_HEIGHT });
760 aCreator.AutoPlaceCaption();
782 SAL_WARN_IF( !pDrawPage,
"sc.core",
"ScCaptionPtr::removeFromDrawPageAndFree - object without drawing page");
787 bool bRecording = (pDrawLayer && pDrawLayer->
IsRecording());
796 SAL_INFO(
"sc.core",
"ScPostIt::RemoveCaption -"
803 SAL_INFO(
"sc.core",
"ScPostIt::RemoveCaption - forgetting one ref");
810 uno::Reference<drawing::XShape> xShape = pCaption->
getUnoShape();
811 uno::Reference<text::XText> xText(xShape, uno::UNO_QUERY);
812 uno::Reference<text::XTextAppend> xBodyTextAppend(xText, uno::UNO_QUERY);
814 if (xBodyTextAppend.is())
816 uno::Sequence< beans::PropertyValue > aArgs;
817 if (bUserWithTrackText)
819 xBodyTextAppend->insertTextPortion(aUserData.makeStringAndClear(), aArgs, xText->getStart());
823 xBodyTextAppend->insertTextPortion(
"\n--------\n", aArgs, xText->getStart());
827 xBodyTextAppend->insertTextPortion(aUserData.makeStringAndClear(), aArgs, xText->getStart());
834 std::u16string_view rUserText,
const tools::Rectangle& rVisRect,
bool bTailFront )
836 bool bUserWithTrackText =
false;
837 OUStringBuffer
aBuffer( rUserText );
845 bUserWithTrackText =
true;
846 aBuffer.append(
"\n--------\n");
859 rVisRect.
Left() + SC_NOTECAPTION_BORDERDIST_TEMP,
860 rVisRect.
Top() + SC_NOTECAPTION_BORDERDIST_TEMP,
861 rVisRect.
Right() - SC_NOTECAPTION_BORDERDIST_TEMP,
862 rVisRect.
Bottom() - SC_NOTECAPTION_BORDERDIST_TEMP );
865 ScCaptionCreator aCreator( rDoc, rPos, bTailFront );
875 pCaption->SetOutlinerParaObject( *pOPO );
880 pCaption->SetStyleSheet(pStyleSheet,
true);
885 pCaption->SetText(
aBuffer.makeStringAndClear());
887 pCaption->SetStyleSheet(
static_cast<SfxStyleSheet*
>(pStyleSheet),
true);
891 tools::Long nMaxWidth = ::std::min< tools::Long >( aVisRect.
GetWidth() * 2 / 3, SC_NOTECAPTION_MAXWIDTH_TEMP );
896 pCaption->AdjustTextFrameWidthAndHeight();
899 aCreator.AutoPlaceCaption( &aVisRect );
902 return aCreator.GetCaption();
913 rDoc.
SetNote(rPos, std::unique_ptr<ScPostIt>(pNote));
916 ScNoteCaptionCreator aCreator( rDoc, rPos, aNoteData.
mxCaption,
true );
938 aNoteData.
mxInitData = std::make_shared<ScCaptionInitData>();
940 rInitData.
moItemSet.emplace(std::move(rItemSet));
957 ScPostIt* pNote =
new ScPostIt( rDoc, rPos, std::move(aNoteData),
false, 0 );
960 rDoc.
SetNote(rPos, std::unique_ptr<ScPostIt>(pNote));
967 bool bShown,
bool bAlwaysCreateCaption, sal_uInt32 nPostItId )
970 if( !rNoteText.isEmpty() )
973 aNoteData.
mxInitData = std::make_shared<ScCaptionInitData>();
981 pNote =
new ScPostIt( rDoc, rPos, std::move(aNoteData), bAlwaysCreateCaption, nPostItId );
984 rDoc.
SetNote(rPos, std::unique_ptr<ScPostIt>(pNote));
992 maPos(rPos), mpNote(pNote) {}
OUString GetText(LineEnd eEnd=LINEEND_LF) const
sal_Int32 GetParagraphCount() const
OUString getDate(const Date &rDate) const
OUString getTime(const tools::Time &rTime, bool bSec=true, bool b100Sec=false) const
const EditTextObject & GetTextObject() const
constexpr tools::Long Y() const
void setX(tools::Long nX)
void setY(tools::Long nY)
tools::Long AdjustY(tools::Long nVertMove)
tools::Long AdjustX(tools::Long nHorzMove)
constexpr tools::Long X() const
void SetNote(const ScAddress &rPos, std::unique_ptr< ScPostIt > pNote)
SC_DLLPUBLIC void InitDrawLayer(SfxObjectShell *pDocShell=nullptr)
SC_DLLPUBLIC ScPostIt * GetNote(const ScAddress &rPos)
SC_DLLPUBLIC bool IsNegativePage(SCTAB nTab) const
SC_DLLPUBLIC ScDrawLayer * GetDrawLayer()
SC_DLLPUBLIC ScNoteEditEngine & GetNoteEngine()
SC_DLLPUBLIC ScStyleSheetPool * GetStyleSheetPool() const
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 * CreateNoteFromCaption(ScDocument &rDoc, const ScAddress &rPos, SdrCaptionObj *pCaption, bool bHasStyle)
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 ScPostIt * CreateNoteFromObjectData(ScDocument &rDoc, const ScAddress &rPos, SfxItemSet &&oItemSet, const OUString &rStyleName, const OutlinerParaObject &rOutlinerObj, const tools::Rectangle &rCaptionRect, bool bShown)
Creates a cell note based on the passed caption object data.
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.
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.
const OUString & GetDate() const
Returns the creation date of this note.
const OUString & GetAuthor() const
Returns the author date of this note.
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.
void CreateCaption(const ScAddress &rPos, const SdrCaptionObj *pCaption=nullptr)
Creates a new caption object at the passed cell position, clones passed existing caption.
static SC_DLLPUBLIC OUString ProgrammaticToDisplayName(const OUString &rProgName, SfxStyleFamily nType)
void CopyStyleFrom(SfxStyleSheetBasePool *pSrcPool, const OUString &rName, SfxStyleFamily eFamily, bool bNewStyleHierarchy=false)
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)
virtual css::uno::Reference< css::drawing::XShape > getUnoShape()
void SetMergedItemSet(const SfxItemSet &rSet, bool bClearAllItems=false)
SfxStyleSheet * GetStyleSheet() const
const SfxItemSet & GetMergedItemSet() const
virtual SdrLayerID GetLayer() const
virtual void SetLayer(SdrLayerID nLayer)
virtual OutlinerParaObject * GetOutlinerParaObject() const override
sal_uInt16 ClearItem(sal_uInt16 nWhich=0)
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
virtual SfxStyleSheetBase * Find(const OUString &, SfxStyleFamily eFam, SfxStyleSearchBits n=SfxStyleSearchBits::All)
constexpr SdrLayerID SC_LAYER_HIDDEN(4)
constexpr SdrLayerID SC_LAYER_INTERN(2)
#define SAL_WARN_IF(condition, area, stream)
#define SAL_INFO(area, stream)
css::beans::PropertyValue makePropertyValue(const OUString &rName, T &&rValue)
CAUTION! The following defines must be in the same namespace as the respective type.
static void lcl_FormatAndInsertAuthorAndDatepara(SdrCaptionObj *pCaption, OUStringBuffer &aUserData, bool bUserWithTrackText)
OUString ScResId(TranslateId aId)
SdrMetricItem makeSdrShadowXDistItem(tools::Long nDist)
SdrMetricItem makeSdrShadowYDistItem(tools::Long nDist)
SdrOnOffItem makeSdrTextAutoGrowHeightItem(bool bAuto)
SdrOnOffItem makeSdrTextAutoGrowWidthItem(bool bAuto)
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
Drawing style associated with the caption object.
bool mbDefaultPosSize
Size of the caption object.
OUString maStyleName
Text object with all text portion formatting.
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)
constexpr TypedWhichId< SdrOnOffItem > SDRATTR_SHADOW(SDRATTR_SHADOW_FIRST+0)
std::unique_ptr< char[]> aBuffer