/src/libreoffice/sw/source/uibase/inc/conttree.hxx
Line | Count | Source |
1 | | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | /* |
3 | | * This file is part of the LibreOffice project. |
4 | | * |
5 | | * This Source Code Form is subject to the terms of the Mozilla Public |
6 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
7 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
8 | | * |
9 | | * This file incorporates work covered by the following license notice: |
10 | | * |
11 | | * Licensed to the Apache Software Foundation (ASF) under one or more |
12 | | * contributor license agreements. See the NOTICE file distributed |
13 | | * with this work for additional information regarding copyright |
14 | | * ownership. The ASF licenses this file to you under the Apache |
15 | | * License, Version 2.0 (the "License"); you may not use this file |
16 | | * except in compliance with the License. You may obtain a copy of |
17 | | * the License at http://www.apache.org/licenses/LICENSE-2.0 . |
18 | | */ |
19 | | #ifndef INCLUDED_SW_SOURCE_UIBASE_INC_CONTTREE_HXX |
20 | | #define INCLUDED_SW_SOURCE_UIBASE_INC_CONTTREE_HXX |
21 | | |
22 | | #include <svl/lstner.hxx> |
23 | | #include <vcl/timer.hxx> |
24 | | #include <vcl/transfer.hxx> |
25 | | #include <vcl/weld.hxx> |
26 | | #include <ndarr.hxx> |
27 | | #include "swcont.hxx" |
28 | | |
29 | | #include <map> |
30 | | #include <memory> |
31 | | |
32 | | #include <o3tl/enumarray.hxx> |
33 | | #include <o3tl/typed_flags_set.hxx> |
34 | | |
35 | | #include <svx/sdr/overlay/overlayobject.hxx> |
36 | | #include <editsh.hxx> |
37 | | #include <edglbldc.hxx> |
38 | | |
39 | | class SwWrtShell; |
40 | | class SwContentType; |
41 | | class SwNavigationPI; |
42 | | class SwNavigationConfig; |
43 | | class SfxObjectShell; |
44 | | class SdrObject; |
45 | | |
46 | | enum class EditEntryMode |
47 | | { |
48 | | EDIT = 0, |
49 | | UPD_IDX = 1, |
50 | | UNPROTECT_TABLE = 2, |
51 | | DELETE = 3, |
52 | | RENAME = 4, |
53 | | TEXT_ALTERNATIVE = 5 |
54 | | }; |
55 | | |
56 | | // Flags for PopupMenu-enable/disable |
57 | | enum class MenuEnableFlags { |
58 | | NONE = 0x0000, |
59 | | InsertIdx = 0x0001, |
60 | | InsertFile = 0x0002, |
61 | | InsertText = 0x0004, |
62 | | Edit = 0x0008, |
63 | | Delete = 0x0010, |
64 | | Update = 0x0020, |
65 | | UpdateSel = 0x0040, |
66 | | EditLink = 0x0080 |
67 | | }; |
68 | | namespace o3tl { |
69 | | template<> struct typed_flags<MenuEnableFlags> : is_typed_flags<MenuEnableFlags, 0x00ff> {}; |
70 | | } |
71 | | |
72 | | class SwContentTree; |
73 | | |
74 | | class SwContentTreeDropTarget final : public DropTargetHelper |
75 | | { |
76 | | private: |
77 | | SwContentTree& m_rTreeView; |
78 | | |
79 | | virtual sal_Int8 AcceptDrop( const AcceptDropEvent& rEvt ) override; |
80 | | virtual sal_Int8 ExecuteDrop( const ExecuteDropEvent& rEvt ) override; |
81 | | |
82 | | public: |
83 | | SwContentTreeDropTarget(SwContentTree& rTreeView); |
84 | | }; |
85 | | |
86 | | /** TreeListBox for content indicator */ |
87 | | class SwContentTree final : public SfxListener |
88 | | { |
89 | | friend class SwNavigationPI; |
90 | | |
91 | | std::unique_ptr<weld::TreeView> m_xTreeView; |
92 | | SwContentTreeDropTarget m_aDropTargetHelper; |
93 | | SwNavigationPI* m_pDialog; |
94 | | OUString m_sSpace; |
95 | | AutoTimer m_aUpdTimer; |
96 | | AutoTimer m_aOverlayObjectDelayTimer; |
97 | | |
98 | | o3tl::enumarray<ContentTypeId,std::unique_ptr<SwContentType>> m_aActiveContentArr; |
99 | | o3tl::enumarray<ContentTypeId,std::unique_ptr<SwContentType>> m_aHiddenContentArr; |
100 | | OUString m_aContextStrings[CONTEXT_COUNT + 1]; |
101 | | OUString m_sInvisible; |
102 | | OUString m_sSelectedItem; // last selected item (only bookmarks yet) |
103 | | |
104 | | SwWrtShell* m_pHiddenShell; // dropped Doc |
105 | | SwWrtShell* m_pActiveShell; // the active or a const. open view |
106 | | SwNavigationConfig* m_pConfig; |
107 | | |
108 | | // these maps store the expand state of nodes with children |
109 | | std::map< void*, bool > mOutLineNodeMap; |
110 | | std::map<const void*, bool> m_aRegionNodeExpandMap; |
111 | | std::map<const void*, bool> m_aPostItNodeExpandMap; |
112 | | |
113 | | sal_Int32 m_nActiveBlock; // used to restore content types expand state |
114 | | sal_Int32 m_nHiddenBlock; |
115 | | size_t m_nEntryCount; |
116 | | ContentTypeId m_nRootType; // content type that is currently displayed in the tree |
117 | | ContentTypeId m_nLastSelType; |
118 | | sal_uInt8 m_nOutlineLevel; |
119 | | |
120 | | sal_uInt8 m_nOutlineTracking = 1; // 1 default, 2 focus, 3 off |
121 | | o3tl::enumarray<ContentTypeId, bool> mTrackContentType; |
122 | | |
123 | | SwOutlineNodes::size_type m_nLastGotoContentWasOutlinePos = SwOutlineNodes::npos; |
124 | | |
125 | | enum class State { ACTIVE, CONSTANT, HIDDEN } m_eState; |
126 | | |
127 | | bool m_bIsRoot :1; |
128 | | bool m_bIsIdleClear :1; |
129 | | bool m_bIsLastReadOnly :1; |
130 | | bool m_bIsOutlineMoveable :1; |
131 | | bool m_bViewHasChanged :1; |
132 | | |
133 | | // outline root mode drag & drop |
134 | | std::vector<SwOutlineNodes::size_type> m_aDndOutlinesSelected; |
135 | | |
136 | | bool m_bDocHasChanged = true; |
137 | | bool m_bIgnoreDocChange = false; // used to prevent tracking update |
138 | | |
139 | | ImplSVEvent* m_nRowActivateEventId = nullptr; |
140 | | bool m_bSelectTo = false; |
141 | | |
142 | | bool m_bEditing = false; |
143 | | |
144 | | std::unique_ptr<weld::TreeIter> m_xOverlayCompareEntry; |
145 | | std::unique_ptr<sdr::overlay::OverlayObject> m_xOverlayObject; |
146 | | |
147 | | void OverlayObject(std::vector<basegfx::B2DRange>&& aRanges = {}); |
148 | | |
149 | | void BringEntryToAttention(const weld::TreeIter& rEntry); |
150 | | void BringFramesToAttention(const std::vector<const SwFrameFormat*>& rFrameFormats); |
151 | | void BringBookmarksToAttention(const std::vector<SwMarkName>& rNames); |
152 | | void BringURLFieldsToAttention(const SwGetINetAttrs& rINetAttrsArr); |
153 | | void BringReferencesToAttention(std::vector<const SwTextAttr*>& rTextAttrsArr); |
154 | | void BringPostItFieldsToAttention(std::vector<const SwTextAttr*>& rTextAttrsArr); |
155 | | void BringDrawingObjectsToAttention(std::vector<const SdrObject*>& rDrawingObjectsArr); |
156 | | void BringTextFieldsToAttention(std::vector<const SwTextAttr*>& rTextAttrsArr); |
157 | | void BringFootnotesToAttention(std::vector<const SwTextAttr*>& rTextAttrsArr); |
158 | | void BringTypesWithFlowFramesToAttention(const std::vector<const SwNode*>& rNodes, |
159 | | const bool bIncludeTopMargin = true); |
160 | | |
161 | | /** |
162 | | * Before any data will be deleted, the last active entry has to be found. |
163 | | * After this the UserData will be deleted |
164 | | */ |
165 | | void FindActiveTypeAndRemoveUserData(); |
166 | | |
167 | | void InsertContent(const weld::TreeIter& rParent); |
168 | | |
169 | | void insert(const weld::TreeIter* pParent, const OUString& rStr, const OUString& rId, |
170 | | bool bChildrenOnDemand, weld::TreeIter* pRet); |
171 | | |
172 | | void remove(const weld::TreeIter& rIter); |
173 | | |
174 | | SwNavigationPI* GetParentWindow(); |
175 | | |
176 | | bool FillTransferData(TransferDataContainer& rTransfer); |
177 | | |
178 | | /** Check if the displayed content is valid. */ |
179 | | bool HasContentChanged(); |
180 | | |
181 | | size_t GetAbsPos(const weld::TreeIter& rIter); |
182 | | |
183 | | void EditEntry(const weld::TreeIter& rEntry, EditEntryMode nMode); |
184 | | |
185 | | void GotoContent(const SwContent* pCnt); |
186 | | |
187 | | void ExecuteContextMenuAction(const OUString& rSelectedPopupEntry); |
188 | | |
189 | | void DeleteOutlineSelections(); |
190 | | void CopyOutlineSelections(); |
191 | | |
192 | | size_t GetEntryCount() const; |
193 | | |
194 | | size_t GetChildCount(const weld::TreeIter& rParent) const; |
195 | | |
196 | | std::unique_ptr<weld::TreeIter> GetEntryAtAbsPos(size_t nAbsPos) const; |
197 | | |
198 | | void Expand(const weld::TreeIter& rParent, std::vector<std::unique_ptr<weld::TreeIter>>* pNodesToExpand); |
199 | | |
200 | | void MoveOutline(SwOutlineNodes::size_type nTargetPos); |
201 | | |
202 | | void UpdateLastSelType(); |
203 | | |
204 | | bool IsDeletable(const weld::TreeIter& rEntry); |
205 | | bool IsDeletable(const SwContent* pContent); |
206 | | void DeleteAllContentOfEntryContentType(const weld::TreeIter& rEntry); |
207 | | |
208 | | bool IsSelectedEntryCurrentDocCursorPosition(const weld::TreeIter& rEntry); |
209 | | |
210 | | /** Expand - Remember the state for content types */ |
211 | | DECL_LINK(ExpandHdl, const weld::TreeIter&, bool); |
212 | | /** Collapse - Remember the state for content types. */ |
213 | | DECL_LINK(CollapseHdl, const weld::TreeIter&, bool); |
214 | | DECL_LINK(ContentDoubleClickHdl, weld::TreeView&, bool); |
215 | | DECL_LINK(AsyncContentDoubleClickHdl, void*, void); |
216 | | DECL_LINK(SelectHdl, weld::TreeView&, void); |
217 | | DECL_LINK(FocusInHdl, weld::Widget&, void); |
218 | | DECL_LINK(KeyInputHdl, const KeyEvent&, bool); |
219 | | DECL_LINK(CommandHdl, const CommandEvent&, bool); |
220 | | DECL_LINK(QueryTooltipHdl, const weld::TreeIter&, OUString); |
221 | | DECL_LINK(DragBeginHdl, bool&, bool); |
222 | | DECL_LINK(TimerUpdate, Timer *, void); |
223 | | DECL_LINK(OverlayObjectDelayTimerHdl, Timer *, void); |
224 | | DECL_LINK(MouseMoveHdl, const MouseEvent&, bool); |
225 | | DECL_LINK(MousePressHdl, const MouseEvent&, bool); |
226 | | |
227 | | DECL_LINK(EditingEntryHdl, const weld::TreeIter&, bool); |
228 | | typedef std::pair<const weld::TreeIter&, OUString> IterString; |
229 | | DECL_LINK(EditedEntryHdl, const IterString&, bool); |
230 | | |
231 | | public: |
232 | | SwContentTree(std::unique_ptr<weld::TreeView> xTreeView, SwNavigationPI* pDialog); |
233 | | ~SwContentTree(); |
234 | | SdrObject* GetDrawingObjectsByContent(const SwContent *pCnt); |
235 | | |
236 | | /** Switch the display to Root */ |
237 | | void ToggleToRoot(); |
238 | | void SetRootType(ContentTypeId nType); |
239 | | |
240 | | /** Show the file */ |
241 | | void Display( bool bActiveView ); |
242 | | /** In the clear the content types have to be deleted, also. */ |
243 | | void clear(); |
244 | | |
245 | | /** After a file is dropped on the Navigator, the new shell will be set */ |
246 | | void SetHiddenShell(SwWrtShell* pSh); |
247 | | void ShowHiddenShell(); |
248 | | void ShowActualView(); |
249 | | |
250 | | /** Document change - set new Shell */ |
251 | | void SetActiveShell(SwWrtShell* pSh); |
252 | | |
253 | | /** Set an open view as active. */ |
254 | | void SetConstantShell(SwWrtShell* pSh); |
255 | | |
256 | | SwWrtShell* GetWrtShell() |
257 | 0 | { return State::HIDDEN == m_eState ? m_pHiddenShell : m_pActiveShell; } |
258 | | |
259 | | bool IsInDrag() const; |
260 | | bool HasHeadings() const; |
261 | | |
262 | 0 | sal_uInt8 GetOutlineLevel()const {return m_nOutlineLevel;} |
263 | | void SetOutlineLevel(sal_uInt8 nSet); |
264 | | |
265 | | void SetOutlineTracking(sal_uInt8 nSet); |
266 | | void SetContentTypeTracking(ContentTypeId eCntTypeId, bool bSet); |
267 | | |
268 | | /** Execute commands of the Navigator */ |
269 | | void ExecCommand(std::u16string_view rCmd, bool bModifier); |
270 | | |
271 | | void ShowTree(); |
272 | | void HideTree(); |
273 | | |
274 | 0 | bool IsConstantView() const { return State::CONSTANT == m_eState; } |
275 | 0 | bool IsActiveView() const { return State::ACTIVE == m_eState; } |
276 | 0 | bool IsHiddenView() const { return State::HIDDEN == m_eState; } |
277 | | |
278 | 0 | const SwWrtShell* GetActiveWrtShell() const {return m_pActiveShell;} |
279 | 0 | SwWrtShell* GetHiddenWrtShell() {return m_pHiddenShell;} |
280 | | |
281 | | void UpdateContentFunctionsToolbar(); |
282 | | |
283 | | void UpdateTracking(); |
284 | | void SelectOutlinesWithSelection(); |
285 | | void SelectContentType(std::u16string_view rContentTypeName); |
286 | | void BringCommentToAttention(sal_uInt16 nCommentId); |
287 | | |
288 | | // return true if it has any children |
289 | | bool RequestingChildren(const weld::TreeIter& rParent); |
290 | | |
291 | | void ExpandAllHeadings(); |
292 | | |
293 | | virtual void Notify(SfxBroadcaster& rBC, SfxHint const& rHint) override; |
294 | | |
295 | | sal_Int8 AcceptDrop(const AcceptDropEvent& rEvt); |
296 | | sal_Int8 ExecuteDrop(const ExecuteDropEvent& rEvt); |
297 | | |
298 | | bool IsDropFormatSupported(SotClipboardFormatId nFormat) |
299 | 0 | { |
300 | 0 | return m_aDropTargetHelper.IsDropFormatSupported(nFormat); |
301 | 0 | } |
302 | | |
303 | | void set_accessible_name(const OUString& rName) |
304 | 0 | { |
305 | 0 | m_xTreeView->set_accessible_name(rName); |
306 | 0 | } |
307 | | |
308 | | void grab_focus() |
309 | 0 | { |
310 | 0 | m_xTreeView->grab_focus(); |
311 | 0 | } |
312 | | |
313 | | void set_selection_mode(SelectionMode eMode) |
314 | 0 | { |
315 | 0 | m_xTreeView->set_selection_mode(eMode); |
316 | 0 | } |
317 | | |
318 | | weld::TreeView& get_widget() |
319 | 0 | { |
320 | 0 | return *m_xTreeView; |
321 | 0 | } |
322 | | }; |
323 | | |
324 | | namespace sfx2 { class DocumentInserter; } |
325 | | namespace sfx2 { class FileDialogHelper; } |
326 | | |
327 | | class SwGlobalTree; |
328 | | |
329 | | class SwGlobalTreeDropTarget final : public DropTargetHelper |
330 | | { |
331 | | private: |
332 | | SwGlobalTree& m_rTreeView; |
333 | | |
334 | | virtual sal_Int8 AcceptDrop( const AcceptDropEvent& rEvt ) override; |
335 | | virtual sal_Int8 ExecuteDrop( const ExecuteDropEvent& rEvt ) override; |
336 | | |
337 | | public: |
338 | | SwGlobalTreeDropTarget(SwGlobalTree& rTreeView); |
339 | | }; |
340 | | |
341 | | class SwGlobalTree final : public SfxListener |
342 | | { |
343 | | private: |
344 | | std::unique_ptr<weld::TreeView> m_xTreeView; |
345 | | SwGlobalTreeDropTarget m_aDropTargetHelper; |
346 | | SwNavigationPI* m_pDialog; |
347 | | AutoTimer m_aUpdateTimer; |
348 | | OUString m_aContextStrings[GLOBAL_CONTEXT_COUNT]; |
349 | | |
350 | | SwWrtShell* m_pActiveShell; |
351 | | std::unique_ptr<SwGlblDocContents> m_pSwGlblDocContents; // array with sorted content |
352 | | |
353 | | std::optional<SwGlblDocContent> m_oDocContent; |
354 | | std::unique_ptr<sfx2::DocumentInserter> m_pDocInserter; |
355 | | |
356 | | static const SfxObjectShell* s_pShowShell; |
357 | | |
358 | | void InsertRegion( const SwGlblDocContent* _pContent, |
359 | | const css::uno::Sequence< OUString >& _rFiles ); |
360 | | |
361 | | DECL_LINK( DialogClosedHdl, sfx2::FileDialogHelper*, void ); |
362 | | |
363 | | void Select(); |
364 | | |
365 | | DECL_LINK(Timeout, Timer*, void); |
366 | | DECL_LINK(DoubleClickHdl, weld::TreeView&, bool); |
367 | | DECL_LINK(SelectHdl, weld::TreeView&, void); |
368 | | DECL_LINK(FocusInHdl, weld::Widget&, void); |
369 | | DECL_LINK(KeyInputHdl, const KeyEvent&, bool); |
370 | | DECL_LINK(CommandHdl, const CommandEvent&, bool); |
371 | | DECL_LINK(QueryTooltipHdl, const weld::TreeIter&, OUString); |
372 | | |
373 | | SwNavigationPI* GetParentWindow(); |
374 | | |
375 | | void OpenDoc(const SwGlblDocContent*); |
376 | | void GotoContent(const SwGlblDocContent*); |
377 | | MenuEnableFlags GetEnableFlags() const; |
378 | | |
379 | 0 | static void SetShowShell(const SfxObjectShell*pSet) {s_pShowShell = pSet;} |
380 | | DECL_STATIC_LINK(SwGlobalTree, ShowFrameHdl, void*, void); |
381 | | |
382 | | public: |
383 | | SwGlobalTree(std::unique_ptr<weld::TreeView> xTreeView, SwNavigationPI* pDialog); |
384 | | ~SwGlobalTree(); |
385 | | |
386 | 0 | bool get_visible() const { return m_xTreeView->get_visible(); } |
387 | | |
388 | | void set_accessible_name(const OUString& rName) |
389 | 0 | { |
390 | 0 | m_xTreeView->set_accessible_name(rName); |
391 | 0 | } |
392 | | |
393 | | void grab_focus() |
394 | 0 | { |
395 | 0 | m_xTreeView->grab_focus(); |
396 | 0 | } |
397 | | |
398 | | void set_selection_mode(SelectionMode eMode) |
399 | 0 | { |
400 | 0 | m_xTreeView->set_selection_mode(eMode); |
401 | 0 | } |
402 | | |
403 | | weld::TreeView& get_widget() |
404 | 0 | { |
405 | 0 | return *m_xTreeView; |
406 | 0 | } |
407 | | |
408 | | void MoveSelectionTo(const weld::TreeIter* pDropTarget); |
409 | | |
410 | | void TbxMenuHdl(std::u16string_view rCommand, weld::Menu& rMenu); |
411 | | void InsertRegion( const SwGlblDocContent* pCont, |
412 | | const OUString* pFileName = nullptr ); |
413 | | void EditContent(const SwGlblDocContent* pCont ); |
414 | | |
415 | | void ShowTree(); |
416 | | void HideTree(); |
417 | | |
418 | | void ExecCommand(std::u16string_view rCmd); |
419 | | |
420 | | void Display(bool bOnlyUpdateUserData = false); |
421 | | |
422 | | bool Update(bool bHard); |
423 | | |
424 | | void ExecuteContextMenuAction(std::u16string_view rSelectedPopupEntry); |
425 | | |
426 | 0 | const SwWrtShell* GetActiveWrtShell() const {return m_pActiveShell;} |
427 | | |
428 | | virtual void Notify(SfxBroadcaster& rBC, SfxHint const& rHint) override; |
429 | | void UpdateTracking(); |
430 | | }; |
431 | | |
432 | | #endif |
433 | | |
434 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |