diff options
author | Attila Bakos (NISZ) <bakos.attilakaroly@nisz.hu> | 2021-11-03 15:39:32 +0100 |
---|---|---|
committer | László Németh <nemeth@numbertext.org> | 2021-11-24 11:51:07 +0100 |
commit | eabcfb3f18a6944d9ad89cecd3eb3ca7a2259cf3 (patch) | |
tree | d1c66ab6056a467e3fc07bdbf6f07e179cb9e678 /sw/inc | |
parent | becd76743fd7a3ae84404f26b1afb60b923cabb2 (diff) |
tdf#129183 sw: textboxes in group shapes - part 3
Grouping/ungrouping nested groups works now.
Manual test:
1. Insert Shape.
2. Right-click on selected shape, Add Text Box (and some text).
3. Insert a new shape.
4. Select and group the two shapes.
3. Insert a third shape.
4. Select and group the shape and the previously grouped shapes.
The text box remains in the nested shape group.
Details:
1) tdf#144271 memory leak of SwTextBoxHelper, by replacing the
textbox structure vector with std::unordered map, and rethinking
of the ownership of the objects. If a SwFrameFormat dies, and that
is a FLYFRMFMT, it will be deleted from the textbox node and the
FrameFormat table in the doc too, and the drawing will be stay as
it was before. If the dying format is a drawing, all the textboxes,
and the node will be deleted.
2) Introducing the new UNO property TextBoxContent, which is needed
for writerfilter/xmloff later to set a new textbox for the shape
via UNO.
3) Missing parameters are present now for syncing the textbox
parameters.
4) Introducing a new function namely the handleGroupTextBox() to
do the tasks simply with all textboxes in a group shape.
This can handle nested groups as well (group in a group).
Known issues: now copy of nested group objects is implemented
but not enabled, because it causes an assert.
Change-Id: I931886eda01c7a3db93098de10f5e5f48f2f217b
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/124657
Tested-by: László Németh <nemeth@numbertext.org>
Reviewed-by: László Németh <nemeth@numbertext.org>
Diffstat (limited to 'sw/inc')
-rw-r--r-- | sw/inc/textboxhelper.hxx | 74 | ||||
-rw-r--r-- | sw/inc/unomid.h | 4 | ||||
-rw-r--r-- | sw/inc/unoprnms.hxx | 1 |
3 files changed, 51 insertions, 28 deletions
diff --git a/sw/inc/textboxhelper.hxx b/sw/inc/textboxhelper.hxx index 2e5b27cfccb0..10841ed8626c 100644 --- a/sw/inc/textboxhelper.hxx +++ b/sw/inc/textboxhelper.hxx @@ -11,6 +11,7 @@ #define INCLUDED_SW_INC_TEXTBOXHELPER_HXX #include <map> +#include <unordered_map> #include <optional> #include <set> #include <vector> @@ -60,12 +61,16 @@ public: /// the original text in the shape will be copied to the frame /// The textbox is created for the shape given by the pObject parameter. static void create(SwFrameFormat* pShape, SdrObject* pObject, bool bCopyText = false); + /// Sets the given textframe as textbox for the given (group member) shape. + static void set(SwFrameFormat* pShape, SdrObject* pObject, + css::uno::Reference<css::text::XTextFrame> xNew); /// Destroy a TextBox for a shape. If the format has more textboxes /// like group shapes, it will destroy only that textbox what belongs /// to the given pObject shape. static void destroy(const SwFrameFormat* pShape, const SdrObject* pObject); /// Get interface of a shape's TextBox, if there is any. - static css::uno::Any queryInterface(const SwFrameFormat* pShape, const css::uno::Type& rType); + static css::uno::Any queryInterface(const SwFrameFormat* pShape, const css::uno::Type& rType, + SdrObject* pObj = nullptr); /// Sync property of TextBox with the one of the shape. static void syncProperty(SwFrameFormat* pShape, sal_uInt16 nWID, sal_uInt8 nMemberID, @@ -90,7 +95,7 @@ public: /// Sets the surround to through for the textframe of the given shape, /// not to interfere with the layout. Returns true on success. - static bool setWrapThrough(SwFrameFormat* pShape); + static bool setWrapThrough(SwFrameFormat* pShape, SdrObject* pObj = nullptr); /// Sets the anchor of the associated textframe of the given shape, and /// returns true on success. @@ -100,15 +105,20 @@ public: /// returns true on success. static bool doTextBoxPositioning(SwFrameFormat* pShape, SdrObject* pObj); + /// Sets the correct size of textframe depending on the given SdrObject. + static bool setTextBoxSize(const SwFrameFormat* pShape, SdrObject* pObj); + /// Returns true if the anchor different for the given shape, and the /// associated textframe of the given shape. /// Note: In case of AS_CHAR anchor the anchor type must be different, /// because if not, layout breaks, but this situation also handled by /// this function, and returns true in that case too. - static std::optional<bool> isAnchorTypeDifferent(const SwFrameFormat* pShape); + static std::optional<bool> isAnchorTypeDifferent(const SwFrameFormat* pShape, + SdrObject* pObj = nullptr); /// Returns true if the given shape has a valid textframe. - static bool isTextBoxShapeHasValidTextFrame(const SwFrameFormat* pShape); + static bool isTextBoxShapeHasValidTextFrame(const SwFrameFormat* pShape, + SdrObject* pObj = nullptr); // Returns true on success. Synchronize z-order of the text frame of the given textbox // by setting it one level higher than the z-order of the shape of the textbox. @@ -177,6 +187,26 @@ public: /// Undo the effect of saveLinks() + individual resetLink() calls. static void restoreLinks(std::set<ZSortFly>& rOld, std::vector<SwFrameFormat*>& rNew, SavedLink& rSavedLinks); + + /// The following actions are implemented for groupshapes with textboxes too. + /// The selected action will be done for all of the group member textboxes. + enum GroupTextBoxActionType + { + POSITION_SIZE_AND_ANCHOR_CHANGE, + DELETE, + Z_ORDER_CHANGE + }; + + /// Does the selected action with ALL textboxes in the group. + /// Parameters: + /// - pGroupShapeFormat: The frame format of the group shape where the textboxes belongs to. + /// - pGroupObject: The drawing object for the group. + /// - eActionType: The action what the function is supposed to do. + /// WARN: This function will run recursive! ALL textboxes of the group will be handled by + /// the desired action! + static void handleTextBoxGroup(SwFrameFormat* pGroupShapeFormat, + GroupTextBoxActionType eActionType, + SdrObject* pGroupObject = nullptr); }; /// Textboxes are basically textframe + shape pairs. This means one shape has one frame. @@ -185,27 +215,15 @@ public: /// it can have multiple textboxes. class SwTextBoxNode { - // One TextBox-entry - struct SwTextBoxElement - { - // The textframe format - SwFrameFormat* m_pTextBoxFormat; - // The Draw object where the textbox belongs to - SdrObject* m_pDrawObject; - // This is for indicating if the textbox is in special case: for example during undo. - bool m_bIsActive; - }; - - // This vector stores the textboxes what belongs to this node - std::vector<SwTextBoxElement> m_pTextBoxes; + // This map stores the textboxes what belongs to this node + std::unordered_map<const SdrObject*, SwFrameFormat*> m_pTextBoxTable; // This is the pointer to the shape format, which has this node // (and the textboxes) SwFrameFormat* m_pOwnerShapeFormat; - -public: // Not needed. SwTextBoxNode() = delete; +public: // ctor SwTextBoxNode(SwFrameFormat* pOwnerShapeFormat); // dtor @@ -224,24 +242,24 @@ public: // Parameters: // pDrawObject: The shape which have the textbox to be deleted. void DelTextBox(const SdrObject* pDrawObject); + void DelTextBox(SwFrameFormat* pTextBox); // This will return with the frame format of the textbox what belongs // to the given shape (pDrawObject) SwFrameFormat* GetTextBox(const SdrObject* pDrawObject) const; - // Is this textbox has special state, undo for example? - bool IsTextBoxActive(const SdrObject* pDrawObject) const; - - // Setters for the state flag. - void SetTextBoxInactive(const SdrObject* pDrawObject); - void SetTextBoxActive(const SdrObject* pDrawObject); - // If this is a group shape, that returns true. - bool IsGroupTextBox() const; + bool IsGroupTextBoxShape() const; // This returns with the shape what this class belongs to. SwFrameFormat* GetOwnerShape() { return m_pOwnerShapeFormat; }; // This will give the current number of textboxes. - size_t GetTextBoxCount() const { return m_pTextBoxes.size(); }; + size_t GetTextBoxCount() const { return m_pTextBoxTable.size(); }; + + // Gives a const reference to the text box table, useful for undo and grouping. + const std::unordered_map<const SdrObject*, SwFrameFormat*>& GetTextBoxTable() const + { + return m_pTextBoxTable; + }; }; #endif // INCLUDED_SW_INC_TEXTBOXHELPER_HXX diff --git a/sw/inc/unomid.h b/sw/inc/unomid.h index d249b32fc25a..5b6e8a0cb6cd 100644 --- a/sw/inc/unomid.h +++ b/sw/inc/unomid.h @@ -151,6 +151,10 @@ // SwFormatFollowTextFlow #define MID_FOLLOW_TEXT_FLOW 0 +// TextBox +#define MID_TEXTBOX 0 +#define MID_TEXTBOX_CONTENT 1 + #endif /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/inc/unoprnms.hxx b/sw/inc/unoprnms.hxx index 7ef5d0a58cd7..1e16bc413d01 100644 --- a/sw/inc/unoprnms.hxx +++ b/sw/inc/unoprnms.hxx @@ -74,6 +74,7 @@ #define UNO_NAME_FOOTER_RIGHT_MARGIN "FooterRightMargin" #define UNO_NAME_TEXT_RANGE "TextRange" #define UNO_NAME_TEXT_BOX "TextBox" +#define UNO_NAME_TEXT_BOX_CONTENT "TextBoxContent" #define UNO_NAME_NAME "Name" #define UNO_NAME_CHAR_STYLE_NAME "CharStyleName" #define UNO_NAME_ANCHOR_CHAR_STYLE_NAME "AnchorCharStyleName" |