officecfg/registry/data/org/openoffice/Office/UI/WriterCommands.xcu |    8 +
 sw/inc/cmdid.h                                                      |    1 
 sw/qa/uibase/wrtsh/wrtsh.cxx                                        |   22 ++++
 sw/sdi/_textsh.sdi                                                  |    6 +
 sw/sdi/swriter.sdi                                                  |   17 +++
 sw/source/uibase/dochdl/swdtflvr.cxx                                |   10 -
 sw/source/uibase/inc/wrtsh.hxx                                      |    2 
 sw/source/uibase/shells/basesh.cxx                                  |    2 
 sw/source/uibase/shells/textsh.cxx                                  |    5 
 sw/source/uibase/uiview/view.cxx                                    |    4 
 sw/source/uibase/uiview/view2.cxx                                   |    4 
 sw/source/uibase/wrtsh/wrtsh1.cxx                                   |   52 
+++++++++-
 sw/uiconfig/swriter/menubar/menubar.xml                             |    1 
 sw/uiconfig/swriter/menubar/mscompatibleformsmenu.xml               |    1 
 14 files changed, 120 insertions(+), 15 deletions(-)

New commits:
commit 73ed5e36047b6f46b3777bf6f36591ec4babb1f9
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Fri May 20 13:31:45 2022 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Fri May 20 16:55:16 2022 +0200

    sw content controls, picture: add insert UI
    
    - handle the picture case in SwWrtShell::InsertContentControl(): insert
      a placeholder bitmap & create content control around the as-char image
    
    - expose this as a new .uno:InsertPictureContentControl command
    
    - add the new uno command to the default & MS-compatible menus
    
    - rename the SwWrtShell::Insert() overload taking a Graphic to make this
      a bit more readable
    
    Change-Id: I289d6b6a9cd622c585b6cf0ec0c91d6b51ad81ac
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134681
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins

diff --git 
a/officecfg/registry/data/org/openoffice/Office/UI/WriterCommands.xcu 
b/officecfg/registry/data/org/openoffice/Office/UI/WriterCommands.xcu
index 1dad35cc2190..2ca80032ed48 100644
--- a/officecfg/registry/data/org/openoffice/Office/UI/WriterCommands.xcu
+++ b/officecfg/registry/data/org/openoffice/Office/UI/WriterCommands.xcu
@@ -651,6 +651,14 @@
           <value>1</value>
         </prop>
       </node>
+      <node oor:name=".uno:InsertPictureContentControl" oor:op="replace">
+        <prop oor:name="Label" oor:type="xs:string">
+          <value xml:lang="en-US">Insert Picture Content Control</value>
+        </prop>
+        <prop oor:name="Properties" oor:type="xs:int">
+          <value>1</value>
+        </prop>
+      </node>
       <node oor:name=".uno:InsertObjectDialog" oor:op="replace">
         <prop oor:name="Label" oor:type="xs:string">
           <value xml:lang="en-US">Insert Other Objects</value>
diff --git a/sw/inc/cmdid.h b/sw/inc/cmdid.h
index 0e1691d7ec2d..8b102cae3bf1 100644
--- a/sw/inc/cmdid.h
+++ b/sw/inc/cmdid.h
@@ -223,6 +223,7 @@ class SwUINumRuleItem;
 #define FN_INSERT_PAGEBREAK     (FN_INSERT + 23)    /* Page break*/
 #define FN_INSERT_DROPDOWN_CONTENT_CONTROL (FN_INSERT + 24)  /* Dropdown 
content control */
 #define FN_CONTENT_CONTROL_PROPERTIES (FN_INSERT + 25)  /* Content control 
properties */
+#define FN_INSERT_PICTURE_CONTENT_CONTROL (FN_INSERT + 26) /* Picture content 
control */
 #define FN_POSTIT               (FN_INSERT + 29)    /* Insert/edit PostIt */
 #define FN_INSERT_TABLE         (FN_INSERT + 30)    /* Insert Table */
 #define FN_INSERT_STRING        (FN_INSERT+31)
diff --git a/sw/qa/uibase/wrtsh/wrtsh.cxx b/sw/qa/uibase/wrtsh/wrtsh.cxx
index 297e7a2d1ebd..3fd708bf2a48 100644
--- a/sw/qa/uibase/wrtsh/wrtsh.cxx
+++ b/sw/qa/uibase/wrtsh/wrtsh.cxx
@@ -285,6 +285,28 @@ CPPUNIT_TEST_FIXTURE(Test, 
testReplacePictureContentControl)
     // killed the image selection.
     CPPUNIT_ASSERT(pWrtShell->IsFrameSelected());
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testInsertPictureContentControl)
+{
+    // Given an empty document:
+    SwDoc* pDoc = createSwDoc();
+
+    // When inserting a content control:
+    SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+    pWrtShell->InsertContentControl(SwContentControlType::PICTURE);
+
+    // Then make sure that the matching text attribute is added to the 
document model:
+    SwTextNode* pTextNode = pWrtShell->GetCursor()->GetNode().GetTextNode();
+    SwTextAttr* pAttr = pTextNode->GetTextAttrForCharAt(0, 
RES_TXTATR_CONTENTCONTROL);
+    auto pTextContentControl = 
static_txtattr_cast<SwTextContentControl*>(pAttr);
+    auto& rFormatContentControl
+        = static_cast<SwFormatContentControl&>(pTextContentControl->GetAttr());
+    std::shared_ptr<SwContentControl> pContentControl = 
rFormatContentControl.GetContentControl();
+    // Without the accompanying fix in place, this test would have failed, 
there was no special
+    // handling for picture content control, no placeholder fly content was 
inserted.
+    CPPUNIT_ASSERT(pContentControl->GetPicture());
+    CPPUNIT_ASSERT(pTextNode->GetTextAttrForCharAt(1, RES_TXTATR_FLYCNT));
+}
 }
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/sdi/_textsh.sdi b/sw/sdi/_textsh.sdi
index 4c4e042e45a5..6f6ad01a1536 100644
--- a/sw/sdi/_textsh.sdi
+++ b/sw/sdi/_textsh.sdi
@@ -290,6 +290,12 @@ interface BaseText
         StateMethod = NoState ;
         DisableFlags="SfxDisableFlags::SwOnProtectedCursor";
     ]
+    FN_INSERT_PICTURE_CONTENT_CONTROL  // status(final|play)
+    [
+        ExecMethod = ExecInsert ;
+        StateMethod = NoState ;
+        DisableFlags="SfxDisableFlags::SwOnProtectedCursor";
+    ]
     FN_CONTENT_CONTROL_PROPERTIES  // status(final|play)
     [
         ExecMethod = ExecInsert ;
diff --git a/sw/sdi/swriter.sdi b/sw/sdi/swriter.sdi
index 4bd53a1557d9..285f1fdfa7e4 100644
--- a/sw/sdi/swriter.sdi
+++ b/sw/sdi/swriter.sdi
@@ -3083,6 +3083,23 @@ SfxVoidItem InsertDropdownContentControl 
FN_INSERT_DROPDOWN_CONTENT_CONTROL
     GroupId = SfxGroupId::Insert;
 ]
 
+SfxVoidItem InsertPictureContentControl FN_INSERT_PICTURE_CONTENT_CONTROL
+()
+[
+    AutoUpdate = FALSE,
+    FastCall = FALSE,
+    ReadOnlyDoc = FALSE,
+    Toggle = FALSE,
+    Container = FALSE,
+    RecordAbsolute = FALSE,
+    RecordPerSet;
+
+    AccelConfig = TRUE,
+    MenuConfig = TRUE,
+    ToolBoxConfig = TRUE,
+    GroupId = SfxGroupId::Insert;
+]
+
 SfxVoidItem ContentControlProperties FN_CONTENT_CONTROL_PROPERTIES
 ()
 [
diff --git a/sw/source/uibase/dochdl/swdtflvr.cxx 
b/sw/source/uibase/dochdl/swdtflvr.cxx
index 2e81d7495a43..7768414cb4ba 100644
--- a/sw/source/uibase/dochdl/swdtflvr.cxx
+++ b/sw/source/uibase/dochdl/swdtflvr.cxx
@@ -2499,7 +2499,7 @@ bool SwTransferable::PasteTargetURL( const 
TransferableDataHelper& rData,
                 {
                 case SwPasteSdr::Insert:
                     SwTransferable::SetSelInShell( rSh, false, pPt );
-                    rSh.Insert(sURL, OUString(), aGraphic);
+                    rSh.InsertGraphic(sURL, OUString(), aGraphic);
                     break;
 
                 case SwPasteSdr::Replace:
@@ -2521,7 +2521,7 @@ bool SwTransferable::PasteTargetURL( const 
TransferableDataHelper& rData,
                     else
                     {
                         SwTransferable::SetSelInShell( rSh, false, pPt );
-                        rSh.Insert(sURL, OUString(), aGraphic);
+                        rSh.InsertGraphic(sURL, OUString(), aGraphic);
                     }
                     break;
                 default:
@@ -2627,7 +2627,7 @@ bool SwTransferable::PasteDDE( const 
TransferableDataHelper& rData,
             if ( bReReadGrf )
                 rWrtShell.ReRead( aCmd, sLnkTyp, &aGrf );
             else
-                rWrtShell.Insert( aCmd, sLnkTyp, aGrf );
+                rWrtShell.InsertGraphic( aCmd, sLnkTyp, aGrf );
         }
         return bRet;
     }
@@ -2922,7 +2922,7 @@ bool SwTransferable::PasteGrf( const 
TransferableDataHelper& rData, SwWrtShell&
             case SwPasteSdr::Insert:
             {
                 SwTransferable::SetSelInShell( rSh, false, pPt );
-                rSh.Insert(sURL, OUString(), aGraphic, nullptr, nAnchorType);
+                rSh.InsertGraphic(sURL, OUString(), aGraphic, nullptr, 
nAnchorType);
                 break;
             }
 
@@ -2976,7 +2976,7 @@ bool SwTransferable::PasteGrf( const 
TransferableDataHelper& rData, SwWrtShell&
                 else
                 {
                     SwTransferable::SetSelInShell( rSh, false, pPt );
-                    rSh.Insert(aBkmk.GetURL(), OUString(), aGraphic);
+                    rSh.InsertGraphic(aBkmk.GetURL(), OUString(), aGraphic);
                 }
                 break;
             }
diff --git a/sw/source/uibase/inc/wrtsh.hxx b/sw/source/uibase/inc/wrtsh.hxx
index a80f42c8315a..91cb72146fc0 100644
--- a/sw/source/uibase/inc/wrtsh.hxx
+++ b/sw/source/uibase/inc/wrtsh.hxx
@@ -309,7 +309,7 @@ typedef bool (SwWrtShell::*FNSimpleMove)();
     bool    InsertField2(SwField const &, SwPaM* pAnnotationRange = nullptr);
     void    Insert(const OUString &);
     // graphic
-    void    Insert( const OUString &rPath, const OUString &rFilter,
+    void    InsertGraphic( const OUString &rPath, const OUString &rFilter,
                     const Graphic &, SwFlyFrameAttrMgr * = nullptr,
                     RndStdIds nAnchorType = RndStdIds::FLY_AT_PARA);
 
diff --git a/sw/source/uibase/shells/basesh.cxx 
b/sw/source/uibase/shells/basesh.cxx
index c5b46d42d90d..e63384824b43 100644
--- a/sw/source/uibase/shells/basesh.cxx
+++ b/sw/source/uibase/shells/basesh.cxx
@@ -919,7 +919,7 @@ void SwBaseShell::Execute(SfxRequest &rReq)
                 if ( nSelType & SelectionType::Graphic )
                     rSh.ReRead( aGrfName, aFltName, &aGrf );
                 else
-                    rSh.Insert( aGrfName, aFltName, aGrf );
+                    rSh.InsertGraphic( aGrfName, aFltName, aGrf );
 
                 GetView().GetEditWin().GrabFocus();
             }
diff --git a/sw/source/uibase/shells/textsh.cxx 
b/sw/source/uibase/shells/textsh.cxx
index bd624db80afe..ded35969ff39 100644
--- a/sw/source/uibase/shells/textsh.cxx
+++ b/sw/source/uibase/shells/textsh.cxx
@@ -234,6 +234,11 @@ void SwTextShell::ExecInsert(SfxRequest &rReq)
         rReq.Done();
         break;
 
+    case FN_INSERT_PICTURE_CONTENT_CONTROL:
+        rSh.InsertContentControl(SwContentControlType::PICTURE);
+        rReq.Done();
+        break;
+
     case FN_CONTENT_CONTROL_PROPERTIES:
     {
         SwWrtShell& rWrtSh = GetShell();
diff --git a/sw/source/uibase/uiview/view.cxx b/sw/source/uibase/uiview/view.cxx
index 9bec819807ee..359e1b27fa49 100644
--- a/sw/source/uibase/uiview/view.cxx
+++ b/sw/source/uibase/uiview/view.cxx
@@ -593,7 +593,7 @@ void SwView::CheckReadonlyState()
             FN_INSERT_HARDHYPHEN,       FN_INSERT_HARD_SPACE,       
FN_INSERT_NNBSP,
             FN_INSERT_BREAK,            FN_INSERT_LINEBREAK,        
FN_INSERT_COLUMN_BREAK,
             FN_INSERT_BREAK_DLG,        FN_INSERT_CONTENT_CONTROL,  
FN_INSERT_CHECKBOX_CONTENT_CONTROL,
-            FN_INSERT_DROPDOWN_CONTENT_CONTROL,
+            FN_INSERT_DROPDOWN_CONTENT_CONTROL, 
FN_INSERT_PICTURE_CONTENT_CONTROL,
             FN_DELETE_SENT,             FN_DELETE_BACK_SENT,        
FN_DELETE_WORD,
             FN_DELETE_BACK_WORD,        FN_DELETE_LINE,             
FN_DELETE_BACK_LINE,
             FN_DELETE_PARA,             FN_DELETE_BACK_PARA,        
FN_DELETE_WHOLE_LINE,
@@ -1797,7 +1797,7 @@ void SwView::ScannerEventHdl()
                 if( !aScanBmp.IsEmpty() )
                 {
                     Graphic aGrf(aScanBmp);
-                    m_pWrtShell->Insert( OUString(), OUString(), aGrf );
+                    m_pWrtShell->InsertGraphic( OUString(), OUString(), aGrf );
                 }
             }
         }
diff --git a/sw/source/uibase/uiview/view2.cxx 
b/sw/source/uibase/uiview/view2.cxx
index 75219fcbab07..e716c96b31f6 100644
--- a/sw/source/uibase/uiview/view2.cxx
+++ b/sw/source/uibase/uiview/view2.cxx
@@ -287,11 +287,11 @@ ErrCode SwView::InsertGraphic( const OUString &rPath, 
const OUString &rFilter,
                 OUString sURL = URIHelper::SmartRel2Abs(
                     aTemp, rPath, URIHelper::GetMaybeFileHdl() );
                 aGraphic.setOriginURL(sURL);
-                rShell.Insert( sURL, rFilter, aGraphic, &aFrameManager );
+                rShell.InsertGraphic( sURL, rFilter, aGraphic, &aFrameManager 
);
             }
             else
             {
-                rShell.Insert( OUString(), OUString(), aGraphic, 
&aFrameManager );
+                rShell.InsertGraphic( OUString(), OUString(), aGraphic, 
&aFrameManager );
             }
 
             // it is too late after "EndAction" because the Shell can already 
be destroyed.
diff --git a/sw/source/uibase/wrtsh/wrtsh1.cxx 
b/sw/source/uibase/wrtsh/wrtsh1.cxx
index 965a0e309cb5..ea022fc85b31 100644
--- a/sw/source/uibase/wrtsh/wrtsh1.cxx
+++ b/sw/source/uibase/wrtsh/wrtsh1.cxx
@@ -103,6 +103,7 @@
 #include <svx/postattr.hxx>
 #include <comphelper/lok.hxx>
 #include <comphelper/propertyvalue.hxx>
+#include <svtools/optionsdrawinglayer.hxx>
 #include <memory>
 
 #include <frmtool.hxx>
@@ -267,9 +268,9 @@ void SwWrtShell::Insert( const OUString &rStr )
 // Maximum height limit not possible, because the maximum height
 // of the current frame can not be obtained.
 
-void SwWrtShell::Insert( const OUString &rPath, const OUString &rFilter,
-                         const Graphic &rGrf, SwFlyFrameAttrMgr *pFrameMgr,
-                         RndStdIds nAnchorType )
+void SwWrtShell::InsertGraphic( const OUString &rPath, const OUString &rFilter,
+                                const Graphic &rGrf, SwFlyFrameAttrMgr 
*pFrameMgr,
+                                RndStdIds nAnchorType )
 {
     ResetCursorStack();
     if ( !CanInsert() )
@@ -1030,7 +1031,6 @@ void 
SwWrtShell::InsertContentControl(SwContentControlType eType)
     switch (eType)
     {
         case SwContentControlType::RICH_TEXT:
-        case SwContentControlType::PICTURE:
         {
             pContentControl->SetShowingPlaceHolder(true);
             if (!HasSelection())
@@ -1061,6 +1061,50 @@ void 
SwWrtShell::InsertContentControl(SwContentControlType eType)
             pContentControl->SetListItems({ aListItem });
             break;
         }
+        case SwContentControlType::PICTURE:
+        {
+            // Set up the picture content control.
+            pContentControl->SetShowingPlaceHolder(true);
+            pContentControl->SetPicture(true);
+
+            // Create the placeholder bitmap.
+            BitmapEx aBitmap(Size(1, 1), vcl::PixelFormat::N24_BPP);
+            Color aColor = SvtOptionsDrawinglayer::getHilightColor();
+            aColor.IncreaseLuminance(255 * 0.75);
+            aBitmap.Erase(aColor);
+            SwRewriter aRewriter;
+            aRewriter.AddRule(UndoArg1, SwResId(STR_GRAPHIC_DEFNAME));
+            StartUndo(SwUndoId::INSERT, &aRewriter);
+            LockPaint();
+            StartAction();
+            InsertGraphic(OUString(), OUString(), aBitmap, nullptr, 
RndStdIds::FLY_AS_CHAR);
+
+            // Set properties on the bitmap.
+            SfxItemSetFixed<RES_FRM_SIZE, RES_FRM_SIZE> 
aSet(GetDoc()->GetAttrPool());
+            GetFlyFrameAttr(aSet);
+            SwFormatFrameSize aSize(SwFrameSize::Fixed, 3000, 3000);
+            aSet.Put(aSize);
+            SetFlyFrameAttr(aSet);
+            SwFrameFormat* pFrameFormat = GetFlyFrameFormat();
+            EndAction();
+            UnlockPaint();
+            EndUndo();
+
+            // Go after the anchor position.
+            UnSelectFrame();
+            LeaveSelFrameMode();
+            {
+                SwCursor* pCursor = getShellCursor(true);
+                pCursor->DeleteMark();
+                const SwPosition* pAnchor = 
pFrameFormat->GetAnchor().GetContentAnchor();
+                pCursor->GetPoint()->nContent = pAnchor->nContent;
+                ++pCursor->GetPoint()->nContent;
+            }
+
+            // Select before the anchor position.
+            Left(CRSR_SKIP_CHARS, /*bSelect=*/true, 1, /*bBasicCall=*/false);
+            break;
+        }
     }
     if (aPlaceholder.getLength())
     {
diff --git a/sw/uiconfig/swriter/menubar/menubar.xml 
b/sw/uiconfig/swriter/menubar/menubar.xml
index dda9338ce381..9ed30d1bf492 100644
--- a/sw/uiconfig/swriter/menubar/menubar.xml
+++ b/sw/uiconfig/swriter/menubar/menubar.xml
@@ -713,6 +713,7 @@
       <menu:menu menu:id=".uno:ContentControlsMenu">
         <menu:menupopup>
           <menu:menuitem menu:id=".uno:InsertContentControl"/>
+          <menu:menuitem menu:id=".uno:InsertPictureContentControl"/>
           <menu:menuitem menu:id=".uno:InsertCheckboxContentControl"/>
           <menu:menuitem menu:id=".uno:InsertDropdownContentControl"/>
           <menu:menuitem menu:id=".uno:ContentControlProperties"/>
diff --git a/sw/uiconfig/swriter/menubar/mscompatibleformsmenu.xml 
b/sw/uiconfig/swriter/menubar/mscompatibleformsmenu.xml
index 147b4dd03d6e..cc4483cda320 100644
--- a/sw/uiconfig/swriter/menubar/mscompatibleformsmenu.xml
+++ b/sw/uiconfig/swriter/menubar/mscompatibleformsmenu.xml
@@ -16,6 +16,7 @@
       <menu:menu menu:id=".uno:MSCompatContentControls">
         <menu:menupopup>
           <menu:menuitem menu:id=".uno:InsertContentControl"/>
+          <menu:menuitem menu:id=".uno:InsertPictureContentControl"/>
           <menu:menuitem menu:id=".uno:InsertCheckboxContentControl"/>
           <menu:menuitem menu:id=".uno:InsertDropdownContentControl"/>
           <menu:menuitem menu:id=".uno:DatePickerFormField"/>

Reply via email to