tdf#130179 sw comments on frames: limit insert UI for at-char and ...

... as-char anchor types

SwWrtShell::InsertPostIt() only sets the comment anchor for those types,
and we would crash without an anchor.

Change-Id: I7d2f5d3d8f8e11c46db060c17587e97ecb786ad2
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/87542
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins
diff --git a/sw/CppunitTest_sw_uibase_shells.mk b/sw/CppunitTest_sw_uibase_shells.mk
new file mode 100644
index 0000000..a4bb21c
--- /dev/null
+++ b/sw/CppunitTest_sw_uibase_shells.mk
@@ -0,0 +1,70 @@
# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
#*************************************************************************
#
# This file is part of the LibreOffice project.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
#*************************************************************************

$(eval $(call gb_CppunitTest_CppunitTest,sw_uibase_shells))

$(eval $(call gb_CppunitTest_use_common_precompiled_header,sw_uibase_shells))

$(eval $(call gb_CppunitTest_add_exception_objects,sw_uibase_shells, \
    sw/qa/uibase/shells/shells \
))

$(eval $(call gb_CppunitTest_use_libraries,sw_uibase_shells, \
    comphelper \
    cppu \
    cppuhelper \
    sal \
    sfx \
    svl \
    sw \
    test \
    unotest \
    utl \
    vcl \
))

$(eval $(call gb_CppunitTest_use_externals,sw_uibase_shells,\
    boost_headers \
    libxml2 \
))

$(eval $(call gb_CppunitTest_set_include,sw_uibase_shells,\
    -I$(SRCDIR)/sw/inc \
    -I$(SRCDIR)/sw/source/core/inc \
    -I$(SRCDIR)/sw/source/uibase/inc \
    -I$(SRCDIR)/sw/qa/inc \
    $$(INCLUDE) \
))

$(eval $(call gb_CppunitTest_use_api,sw_uibase_shells,\
	udkapi \
	offapi \
	oovbaapi \
))

$(eval $(call gb_CppunitTest_use_ure,sw_uibase_shells))
$(eval $(call gb_CppunitTest_use_vcl,sw_uibase_shells))

$(eval $(call gb_CppunitTest_use_rdb,sw_uibase_shells,services))

$(eval $(call gb_CppunitTest_use_custom_headers,sw_uibase_shells,\
    officecfg/registry \
))

$(eval $(call gb_CppunitTest_use_configuration,sw_uibase_shells))

$(eval $(call gb_CppunitTest_use_uiconfigs,sw_uibase_shells, \
    modules/swriter \
))

$(eval $(call gb_CppunitTest_use_more_fonts,sw_uibase_shells))

# vim: set noet sw=4 ts=4:
diff --git a/sw/Module_sw.mk b/sw/Module_sw.mk
index 17b60a0..0839141 100644
--- a/sw/Module_sw.mk
+++ b/sw/Module_sw.mk
@@ -105,6 +105,7 @@ $(eval $(call gb_Module_add_slowcheck_targets,sw,\
    CppunitTest_sw_apitests \
    CppunitTest_sw_unowriter \
    CppunitTest_sw_core_text \
    CppunitTest_sw_uibase_shells \
    CppunitTest_sw_core_accessibilitycheck \
))

diff --git a/sw/qa/uibase/shells/shells.cxx b/sw/qa/uibase/shells/shells.cxx
new file mode 100644
index 0000000..8701db9
--- /dev/null
+++ b/sw/qa/uibase/shells/shells.cxx
@@ -0,0 +1,74 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include <swmodeltestbase.hxx>

#include <sfx2/dispatch.hxx>
#include <sfx2/viewfrm.hxx>
#include <vcl/GraphicObject.hxx>
#include <vcl/gdimtf.hxx>

#include <IDocumentContentOperations.hxx>
#include <cmdid.h>
#include <fmtanchr.hxx>
#include <view.hxx>
#include <wrtsh.hxx>

static char const DATA_DIRECTORY[] = "/sw/qa/uibase/shells/data/";

/// Covers sw/source/uibase/shells/ fixes.
class SwUibaseShellsTest : public SwModelTestBase
{
public:
    SwDoc* createDoc(const char* pName = nullptr);
};

SwDoc* SwUibaseShellsTest::createDoc(const char* pName)
{
    if (!pName)
        loadURL("private:factory/swriter", nullptr);
    else
        load(DATA_DIRECTORY, pName);

    SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
    CPPUNIT_ASSERT(pTextDoc);
    return pTextDoc->GetDocShell()->GetDoc();
}

CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest, testTdf130179)
{
    SwDoc* pDoc = createDoc();
    IDocumentContentOperations& rIDCO = pDoc->getIDocumentContentOperations();
    SwCursorShell* pShell(pDoc->GetEditShell());
    SfxItemSet aFrameSet(pDoc->GetAttrPool(), svl::Items<RES_FRMATR_BEGIN, RES_FRMATR_END - 1>{});
    SfxItemSet aGrfSet(pDoc->GetAttrPool(), svl::Items<RES_GRFATR_BEGIN, RES_GRFATR_END - 1>{});
    SwFormatAnchor aAnchor(RndStdIds::FLY_AT_PARA);
    aFrameSet.Put(aAnchor);
    GraphicObject aGrf;
    CPPUNIT_ASSERT(rIDCO.InsertGraphicObject(*pShell->GetCursor(), aGrf, &aFrameSet, &aGrfSet));
    CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_GRF));

    SwView* pView = pDoc->GetDocShell()->GetView();
    pView->GetViewFrame()->GetDispatcher()->Execute(FN_CNTNT_TO_NEXT_FRAME, SfxCallMode::SYNCHRON);
    // Make sure SwTextShell is replaced with SwDrawShell right now, not after 120 ms, as set in the
    // SwView ctor.
    pView->StopShellTimer();

    std::unique_ptr<SfxPoolItem> pItem;
    pView->GetViewFrame()->GetBindings().QueryState(FN_POSTIT, pItem);
    // Without the accompanying fix in place, this test would have failed with:
    // assertion failed
    // - Expression: !pItem
    // i.e. comment insertion was enabled for an at-para anchored image.
    CPPUNIT_ASSERT(!pItem);
}

CPPUNIT_PLUGIN_IMPLEMENT();

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/sdi/_frmsh.sdi b/sw/sdi/_frmsh.sdi
index 87df09b..83ece07 100644
--- a/sw/sdi/_frmsh.sdi
+++ b/sw/sdi/_frmsh.sdi
@@ -414,7 +414,7 @@ interface BaseTextFrame
    FN_POSTIT
    [
        ExecMethod = ExecField ;
        StateMethod = NoState ;
        StateMethod = GetState ;
    ]
}

diff --git a/sw/source/uibase/shells/frmsh.cxx b/sw/source/uibase/shells/frmsh.cxx
index 7a5a630..3f139e8 100644
--- a/sw/source/uibase/shells/frmsh.cxx
+++ b/sw/source/uibase/shells/frmsh.cxx
@@ -72,6 +72,7 @@
#include <swslots.hxx>
#include <grfatr.hxx>
#include <fldmgr.hxx>
#include <flyfrm.hxx>

using ::editeng::SvxBorderLine;
using namespace ::com::sun::star;
@@ -1011,6 +1012,26 @@ void SwFrameShell::GetState(SfxItemSet& rSet)
                }
                break;

                case FN_POSTIT:
                {
                    SwFlyFrame* pFly = rSh.GetSelectedFlyFrame();
                    if (pFly)
                    {
                        SwFrameFormat* pFormat = pFly->GetFormat();
                        if (pFormat)
                        {
                            RndStdIds eAnchorId = pFormat->GetAnchor().GetAnchorId();
                            // SwWrtShell::InsertPostIt() only works on as-char and at-char anchored
                            // images.
                            if (eAnchorId != RndStdIds::FLY_AS_CHAR && eAnchorId != RndStdIds::FLY_AT_CHAR)
                            {
                                rSet.DisableItem(nWhich);
                            }
                        }
                    }
                }
                break;

                default:
                    /* do nothing */;
                    break;