tdf#73537 - sc: show author and creation date in calc comments

in temporory mode. Show the author and creation/modification
date of the the comment only in temporory mode. In edit mode, or
visible mode, shows only the original text.

Change-Id: I2c5856e4c6a813dbef4ad55de319f922daa57f67
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153358
Tested-by: Jenkins
Reviewed-by: Maxim Monastirsky <momonasmon@gmail.com>
Reviewed-by: Balazs Varga <balazs.varga.extern@allotropia.de>
(cherry picked from commit da8dead8e9282010893cbd12519e107baf03cd1a)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153705
Reviewed-by: Thorsten Behrens <thorsten.behrens@allotropia.de>
diff --git a/editeng/source/uno/unotext.cxx b/editeng/source/uno/unotext.cxx
index 6f78a4a..1eb84a1 100644
--- a/editeng/source/uno/unotext.cxx
+++ b/editeng/source/uno/unotext.cxx
@@ -2078,11 +2078,43 @@ uno::Reference< text::XTextRange > SAL_CALL SvxUnoTextBase::finishParagraph(
}

uno::Reference< text::XTextRange > SAL_CALL SvxUnoTextBase::insertTextPortion(
        const OUString& /*rText*/,
        const uno::Sequence< beans::PropertyValue >& /*rCharAndParaProps*/,
        const uno::Reference< text::XTextRange>& /*rTextRange*/ )
        const OUString& rText,
        const uno::Sequence< beans::PropertyValue >& rCharAndParaProps,
        const uno::Reference< text::XTextRange>& rTextRange )
{
    SolarMutexGuard aGuard;

    uno::Reference< text::XTextRange > xRet;

    if (!rTextRange.is())
        return xRet;

    SvxUnoTextRangeBase* pRange = comphelper::getFromUnoTunnel<SvxUnoTextRange>(rTextRange);
    if (!pRange)
        return xRet;

    SvxEditSource *pEditSource = GetEditSource();
    SvxTextForwarder *pTextForwarder = pEditSource ? pEditSource->GetTextForwarder() : nullptr;

    if (pTextForwarder)
    {
        pRange->setString(rText);

        ESelection aSelection(pRange->GetSelection());

        pTextForwarder->RemoveAttribs(aSelection);
        pEditSource->UpdateData();

        SfxItemSet aItemSet( *pTextForwarder->GetEmptyItemSetPtr() );
        SvxPropertyValuesToItemSet( aItemSet, rCharAndParaProps,
                ImplGetSvxTextPortionSfxPropertySet(), pTextForwarder, aSelection.nStartPara );
        pTextForwarder->QuickSetAttribs( aItemSet, aSelection);
        rtl::Reference<SvxUnoTextRange> pNewRange = new SvxUnoTextRange( *this );
        xRet = pNewRange;
        pNewRange->SetSelection(aSelection);
        for( const beans::PropertyValue& rProp : rCharAndParaProps )
            pNewRange->setPropertyValue( rProp.Name, rProp.Value );
    }
    return xRet;
}

diff --git a/sc/source/core/data/postit.cxx b/sc/source/core/data/postit.cxx
index dd1a023..106a249 100644
--- a/sc/source/core/data/postit.cxx
+++ b/sc/source/core/data/postit.cxx
@@ -57,6 +57,13 @@
#include <globstr.hrc>
#include <scresid.hxx>
#include <utility>
#include <strings.hrc>

#include <com/sun/star/text/XText.hpp>
#include <com/sun/star/text/XTextAppend.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/awt/FontWeight.hpp>
#include <comphelper/propertyvalue.hxx>

using namespace com::sun::star;

@@ -493,8 +500,10 @@ void ScPostIt::SetAuthor( const OUString& rAuthor )

void ScPostIt::AutoStamp()
{
    maNoteData.maDate = ScGlobal::getLocaleData().getDate( Date( Date::SYSTEM ) );
    maNoteData.maAuthor = SvtUserOptions().GetID();
    maNoteData.maDate = ScGlobal::getLocaleData().getDate( Date( Date::SYSTEM ) ) + " " +
        ScGlobal::getLocaleData().getTime(DateTime(DateTime::SYSTEM), false);
    const OUString aAuthor = SvtUserOptions().GetFullName();
    maNoteData.maAuthor = !aAuthor.isEmpty() ? aAuthor : ScResId(STR_CHG_UNKNOWN_AUTHOR);
}

const OutlinerParaObject* ScPostIt::GetOutlinerObject() const
@@ -793,25 +802,55 @@ void ScPostIt::RemoveCaption()
    }
}

static void lcl_FormatAndInsertAuthorAndDatepara(SdrCaptionObj* pCaption, OUStringBuffer& aUserData, bool bUserWithTrackText)
{
    uno::Reference<drawing::XShape> xShape = pCaption->getUnoShape();
    uno::Reference<text::XText> xText(xShape, uno::UNO_QUERY);
    uno::Reference<text::XTextAppend> xBodyTextAppend(xText, uno::UNO_QUERY);

    if (xBodyTextAppend.is())
    {
        uno::Sequence< beans::PropertyValue > aArgs;
        if (bUserWithTrackText)
        {
            xBodyTextAppend->insertTextPortion(aUserData.makeStringAndClear(), aArgs, xText->getStart());
        }
        else
        {
            xBodyTextAppend->insertTextPortion("\n--------\n", aArgs, xText->getStart());
            aArgs = {
                comphelper::makePropertyValue("CharWeight", uno::Any(awt::FontWeight::BOLD)),
            };
            xBodyTextAppend->insertTextPortion(aUserData.makeStringAndClear(), aArgs, xText->getStart());
        }
    }
}

rtl::Reference<SdrCaptionObj> ScNoteUtil::CreateTempCaption(
        ScDocument& rDoc, const ScAddress& rPos, SdrPage& rDrawPage,
        std::u16string_view rUserText, const tools::Rectangle& rVisRect, bool bTailFront )
{
    bool bUserWithTrackText = false;
    OUStringBuffer aBuffer( rUserText );
    // add plain text of invisible (!) cell note (no formatting etc.)
    SdrCaptionObj* pNoteCaption = nullptr;
    const ScPostIt* pNote = rDoc.GetNote( rPos );
    if( pNote && !pNote->IsCaptionShown() )
    {
        if( !aBuffer.isEmpty() )
            aBuffer.append( "\n--------\n" + pNote->GetText() );
        if (!aBuffer.isEmpty())
        {
            bUserWithTrackText = true;
            aBuffer.append("\n--------\n");
        }
        else
        {
            aBuffer.append(pNote->GetAuthor()
                + ", "
                + pNote->GetDate());
        }
        pNoteCaption = pNote->GetOrCreateCaption( rPos );
    }

    // create a caption if any text exists
    if( !pNoteCaption && aBuffer.isEmpty() )
        return rtl::Reference<SdrCaptionObj>();

    // prepare visible rectangle (add default distance to all borders)
    tools::Rectangle aVisRect(
        rVisRect.Left() + SC_NOTECAPTION_BORDERDIST_TEMP,
@@ -826,34 +865,33 @@ rtl::Reference<SdrCaptionObj> ScNoteUtil::CreateTempCaption(
    rtl::Reference<SdrCaptionObj> pCaption = aCreator.GetCaption();  // just for ease of use
    rDrawPage.InsertObject( pCaption.get() );


    // clone the edit text object, unless user text is present, then set this text
    if( pNoteCaption && rUserText.empty() )
    // clone the edit text object, then seta and format the Author and date text
    if (pNoteCaption)
    {
        if( OutlinerParaObject* pOPO = pNoteCaption->GetOutlinerParaObject() )
            pCaption->SetOutlinerParaObject( *pOPO );
        // Setting and formatting rUserText: Author name and date time
        lcl_FormatAndInsertAuthorAndDatepara(pCaption.get(), aBuffer, bUserWithTrackText);
        // set formatting (must be done after setting text) and resize the box to fit the text
        if (auto pStyleSheet = pNoteCaption->GetStyleSheet())
            pCaption->SetStyleSheet(pStyleSheet, true);
        pCaption->SetMergedItemSetAndBroadcast( pNoteCaption->GetMergedItemSet() );
        tools::Rectangle aCaptRect( pCaption->GetLogicRect().TopLeft(), pNoteCaption->GetLogicRect().GetSize() );
        pCaption->SetLogicRect( aCaptRect );
        pCaption->SetMergedItemSetAndBroadcast(pNoteCaption->GetMergedItemSet());
    }
    else
    {
        // if pNoteCaption is null, then aBuffer contains some text
        pCaption->SetText( aBuffer.makeStringAndClear() );
        pCaption->SetText(aBuffer.makeStringAndClear());
        if (auto pStyleSheet = rDoc.GetStyleSheetPool()->Find(ScResId(STR_STYLENAME_NOTE), SfxStyleFamily::Frame))
            pCaption->SetStyleSheet(static_cast<SfxStyleSheet*>(pStyleSheet), true);
        // adjust caption size to text size
        tools::Long nMaxWidth = ::std::min< tools::Long >( aVisRect.GetWidth() * 2 / 3, SC_NOTECAPTION_MAXWIDTH_TEMP );
        pCaption->SetMergedItem( makeSdrTextAutoGrowWidthItem( true ) );
        pCaption->SetMergedItem( makeSdrTextMinFrameWidthItem( SC_NOTECAPTION_WIDTH ) );
        pCaption->SetMergedItem( makeSdrTextMaxFrameWidthItem( nMaxWidth ) );
        pCaption->SetMergedItem( makeSdrTextAutoGrowHeightItem( true ) );
        pCaption->AdjustTextFrameWidthAndHeight();
    }

    // adjust caption size to text size
    tools::Long nMaxWidth = ::std::min< tools::Long >( aVisRect.GetWidth() * 2 / 3, SC_NOTECAPTION_MAXWIDTH_TEMP );
    pCaption->SetMergedItem( makeSdrTextAutoGrowWidthItem( true ) );
    pCaption->SetMergedItem( makeSdrTextMinFrameWidthItem( SC_NOTECAPTION_WIDTH ) );
    pCaption->SetMergedItem( makeSdrTextMaxFrameWidthItem( nMaxWidth ) );
    pCaption->SetMergedItem( makeSdrTextAutoGrowHeightItem( true ) );
    pCaption->AdjustTextFrameWidthAndHeight();

    // move caption into visible area
    aCreator.AutoPlaceCaption( &aVisRect );

diff --git a/test/source/sheet/xsheetannotationanchor.cxx b/test/source/sheet/xsheetannotationanchor.cxx
index 9fbf4b00..8c8467d 100644
--- a/test/source/sheet/xsheetannotationanchor.cxx
+++ b/test/source/sheet/xsheetannotationanchor.cxx
@@ -28,7 +28,7 @@ void XSheetAnnotationAnchor::testGetAnnotation()
    uno::Reference<sheet::XSheetAnnotation> xAnnotation(xAnchor->getAnnotation(), UNO_SET_THROW);
    CPPUNIT_ASSERT_MESSAGE("Unable to get XSheetAnnotation", xAnnotation.is());

    CPPUNIT_ASSERT_MESSAGE("Unable to check: getAuthor()", xAnnotation->getAuthor().isEmpty());
    CPPUNIT_ASSERT_MESSAGE("Unable to check: getAuthor()", !xAnnotation->getAuthor().isEmpty());
    CPPUNIT_ASSERT_MESSAGE("Unable to check: getDate()", !xAnnotation->getDate().isEmpty());
    CPPUNIT_ASSERT_MESSAGE("Unable to check: getIsVisible()", !xAnnotation->getIsVisible());
    CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to check: getPosition()", table::CellAddress(0, 2, 3),