Version 7.5.1.1, tag libreoffice-7.5.1.1
[LibreOffice.git] / sd / inc / Outliner.hxx
blob8d00cfbbba9ca913ef7018f460b9ac89b940b2c6
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #pragma once
22 #include <svx/svdoutl.hxx>
23 #include "pres.hxx"
24 #include "OutlinerIterator.hxx"
25 #include <editeng/SpellPortions.hxx>
26 #include <memory>
27 #include <utility>
29 class SdrObject;
30 class SdrTextObj;
31 class SdDrawDocument;
33 namespace weld
35 class Window;
38 namespace sd
40 class View;
41 class ViewShell;
42 class Window;
44 /// Describes a single search hit: a set of rectangles on a given page.
45 struct SearchSelection
47 /// 0-based index of the page that has the selection.
48 int m_nPage;
50 /**
51 * List of selection rectangles in twips -- multiple rectangles only in
52 * case the selection spans over more layout lines.
54 OString m_aRectangles;
56 SearchSelection(int nPage, OString aRectangles)
57 : m_nPage(nPage)
58 , m_aRectangles(std::move(aRectangles))
62 bool operator==(const SearchSelection& rOther) const
64 return m_nPage == rOther.m_nPage && m_aRectangles == rOther.m_aRectangles;
68 } // end of namespace sd
70 /** The main purpose of this class is searching and replacing as well as
71 spelling of impress documents. The main part of both tasks lies in
72 iterating over the pages and view modes of a document and apply the
73 respective function to all objects containing text on those pages.
75 <p>Relevant objects: There are two sets of objects to search/spell
76 check. One is the set of all selected objects. The other consists of
77 all objects on all pages in draw-, notes-, and handout view as well as
78 slide- and background view (draw pages and master pages).</p>
80 <p>Iteration: Search/replace and spelling functions operate on shapes
81 containing text. To cover all relevant objects an order has to be
82 defined on the objects. For the set of all selected objects this order
83 is simply the order in which they can be retrieved from the selection
84 object.<br>
85 When there is no selection the order is nested. The three modes of the
86 draw view are on the outer level: draw mode, notes mode, handout mode.
87 The inner level switches between draw pages and master pages. This
88 leads to the following order:
89 <ol>
90 <li>draw pages of draw mode</li>
91 <li>master pages of draw mode</li>
92 <li>draw pages of notes mode</li>
93 <li>master pages of notes mode</li>
94 <li>draw pages of handout mode</li>
95 <li>master pages of handout mode</li>
96 </ol>
97 Iteration starts at the top of the current page. When reaching the end
98 of the document, i.e. the last master page of the handout mode, it jumps
99 to the first draw page of draw mode. In backward searches this order is
100 reversed. When doing a <em>replace all</em> then the whole document is
101 searched for matches starting at the first page of the draw/slide view
102 (or last page of handout/background view even though search
103 direction).</p>
105 <p>The start position is restored after finishing spell checking or
106 replacing all matches in a document.</p>
108 <p>Some related pieces of information:
109 The search dialog (<type>SvxSearchDialog</type>) can be controlled in
110 more than one way:
111 <ul><li>A set of option flags returned by the slot call
112 SID_SEARCH_OPTIONS handled by the
113 <member>SdDrawDocument::GetState()</member> method.</li>
114 <li>The contents of the search item of type
115 <type>SvxSearchItem</type>.</li>
116 <li>The <member>HasSelection()</member> view shell method that returns
117 whether or not a selection exists. However, it is called from the
118 search dialog with an argument so that only text selections are
119 queried. This is only sufficient for searching the outline view.
120 </p>
122 class SdOutliner final : public SdrOutliner
124 public:
125 friend class ::sd::outliner::OutlinerContainer;
127 /** Create a new sd outliner object.
128 @param pDoc
129 The draw document from which to take the content.
130 @param nMode
131 The valid values <const>OutlinerMode::DontKnow</const>,
132 <const>OutlinerMode::TextObject</const>,
133 <const>OutlinerMode::TitleObject</const>,
134 <const>OutlinerMode::OutlineObject</const>, and
135 <const>OutlinerMode::OutlineView</const> are defined in
136 editeng/outliner.hxx.
138 SdOutliner(SdDrawDocument* pDoc, OutlinerMode nMode);
139 virtual ~SdOutliner() override;
140 /// Forbid copy construction and copy assignment
141 SdOutliner(const Outliner&) = delete;
142 SdOutliner& operator=(const Outliner&) = delete;
144 /** Despite the name this method is called prior to spell checking *and*
145 searching and replacing. The position of current view
146 mode/page/object/caret position is remembered and, depending on the
147 search mode, may be restored after finishing searching/spell
148 checking.
150 void PrepareSpelling();
152 /** Initialize a spell check but do not start it yet. This method
153 is a better candidate for the name PrepareSpelling.
155 void StartSpelling();
157 /** Initiate a find and/or replace on the next relevant text object.
158 @return
159 Returns </sal_True> when the search/replace is finished (as
160 indicated by user input to the search dialog). A </sal_False> value
161 indicates that another call to this method is required.
163 bool StartSearchAndReplace(const SvxSearchItem* pSearchItem);
165 /** Iterate over the sentences in all text shapes and stop at the
166 next sentence with spelling errors. While doing so the view
167 mode may be changed and text shapes are set into edit mode.
169 svx::SpellPortions GetNextSpellSentence();
171 /** Release all resources that have been created during the find&replace
172 or spell check.
174 void EndSpelling();
176 /** callback for textconversion */
177 bool ConvertNextDocument() override;
179 /** Starts the text conversion (hangul/hanja or Chinese simplified/traditional)
180 for the current viewshell */
181 void StartConversion(LanguageType nSourceLanguage, LanguageType nTargetLanguage,
182 const vcl::Font* pTargetFont, sal_Int32 nOptions, bool bIsInteractive);
184 /** This is called internally when text conversion is started.
185 The position of current view mode/page/object/caret position
186 is remembered and will be restored after conversion.
188 void BeginConversion();
190 /** Release all resources that have been created during the conversion */
191 void EndConversion();
193 int GetIgnoreCurrentPageChangesLevel() const { return mnIgnoreCurrentPageChangesLevel; };
194 void IncreIgnoreCurrentPageChangesLevel() { mnIgnoreCurrentPageChangesLevel++; };
195 void DecreIgnoreCurrentPageChangesLevel() { mnIgnoreCurrentPageChangesLevel--; };
196 SdDrawDocument* GetDoc() const { return mpDrawDocument; }
198 private:
199 class Implementation;
200 ::std::unique_ptr<Implementation> mpImpl;
202 /// Returns the current outline view
203 OutlinerView* getOutlinerView();
205 /// Specifies whether to search and replace, to spell check or to do a
206 /// text conversion.
207 enum mode
209 SEARCH,
210 SPELL,
211 TEXT_CONVERSION
212 } meMode;
214 /// The view which displays the searched objects.
215 ::sd::View* mpView;
216 /** The view shell containing the view. It is held as weak
217 pointer to avoid keeping it alive when the view is changed
218 during searching.
220 std::weak_ptr<::sd::ViewShell> mpWeakViewShell;
221 /// This window contains the view.
222 VclPtr<::sd::Window> mpWindow;
223 /// The document on whose objects and pages this class operates.
224 SdDrawDocument* mpDrawDocument;
226 /** this is the language that is used for current text conversion.
227 Only valid if meMode is TEXT_CONVERSION.
229 LanguageType mnConversionLanguage;
231 /** While the value of this flag is greater than 0 changes of the current page
232 do not lead to selecting the corresponding text in the outliner.
234 int mnIgnoreCurrentPageChangesLevel;
236 /// Specifies whether the search string has been found so far.
237 bool mbStringFound;
239 /** This flag indicates whether there may exist a match of the search
240 string before/after the current position in the document. It can be
241 set to </sal_False> only when starting from the beginning/end of the
242 document. When reaching the end/beginning with it still be set to
243 </sal_False> then there exists no match and the search can be terminated.
245 bool mbMatchMayExist;
247 /// The number of pages in the current view.
248 sal_uInt16 mnPageCount;
250 /** A <TRUE/> value indicates that the end of the find&replace or spell
251 check has been reached.
253 bool mbEndOfSearch;
255 /** Set to <TRUE/> when an object has been prepared successfully for
256 searching/spell checking. This flag directs the internal iteration
257 which stops when set to </sal_True>.
259 bool mbFoundObject;
261 /** This flag indicates whether to search forward or backwards.
263 bool mbDirectionIsForward;
265 /** This flag indicates that only the selected objects are to be
266 searched.
268 bool mbRestrictSearchToSelection;
270 /** When the search is restricted to the current selection then
271 this list contains pointers to all the objects of the
272 selection. This copy is necessary because during the search
273 process the mark list is modified.
275 ::std::vector<unotools::WeakReference<SdrObject>> maMarkListCopy;
277 /** Current object that may be a text object. The object pointer to
278 corresponds to <member>mnObjIndex</member>. While iterating over the
279 objects on a page <member>mpObj</member> will point to every object
280 while <member>mpTextObj</member> will be set only to valid text
281 objects.
283 SdrObject* mpObj;
285 /** this stores the first object that is used for text conversion.
286 Conversion automatically wraps around the document and stops when it
287 finds this object again.
289 SdrObject* mpFirstObj;
291 /// Candidate for being searched/spell checked.
292 SdrTextObj* mpSearchSpellTextObj;
294 /// Current text to be searched/spelled inside the current text object
295 sal_Int32 mnText;
297 /// Paragraph object of <member>mpTextObj</member>.
298 OutlinerParaObject* mpParaObj;
300 /// The view mode that was active when starting to search/spell check.
301 PageKind meStartViewMode;
303 /// The master page mode that was active when starting to search/spell check.
304 EditMode meStartEditMode;
306 /// The current page index on starting to search/spell check.
307 sal_uInt16 mnStartPageIndex;
309 /// The object in edit mode when searching /spell checking was started
310 /// (if any).
311 SdrObject* mpStartEditedObject;
313 /// The position of the caret when searching /spell checking was started.
314 ESelection maStartSelection;
316 /** The search item contains various attributes that define the type of
317 search. It is set every time the
318 <member>SearchAndReplaceAll</member> method is called.
320 std::unique_ptr<const SvxSearchItem> mpSearchItem;
322 /// The actual object iterator.
323 ::sd::outliner::Iterator maObjectIterator;
324 /// The current position of the object iterator.
325 ::sd::outliner::IteratorPosition maCurrentPosition;
326 /// The position when the search started. Corresponds largely to the
327 /// m?Start* members.
328 ::sd::outliner::Iterator maSearchStartPosition;
329 /** The last valid position describes where the last text object has been
330 found. This position is restored when some dialogs are shown. The
331 position is initially set to the where the search begins.
333 ::sd::outliner::IteratorPosition maLastValidPosition;
335 /** When this flag is true then a PrepareSpelling() is executed when
336 StartSearchAndReplace() is called the next time.
338 bool mbPrepareSpellingPending;
340 /** Initialize the object iterator. Call this method after being
341 invoked from the search or spellcheck dialog. It creates a new
342 iterator pointing at the current object when this has not been done
343 before. It reverses the direction of iteration if the given flag
344 differs from the current direction.
345 @param bDirectionIsForward
346 This flag specifies in which direction to iterator over the
347 objects. If it differs from the current direction the iterator
348 is reversed.
350 void Initialize(bool bDirectionIsForward);
352 /** Do search and replace for whole document.
354 bool SearchAndReplaceAll();
356 /** Do search and replace for next match.
357 @param pSelections
358 When tiled rendering and not 0, then don't emit LOK events, instead
359 assume the caller will do so.
360 @return
361 The return value specifies whether the search ended (</sal_True>) or
362 another call to this method is required (</sal_False>).
364 bool SearchAndReplaceOnce(std::vector<::sd::SearchSelection>* pSelections = nullptr);
366 void sendLOKSearchResultCallback(const std::shared_ptr<sd::ViewShell>& pViewShell,
367 const OutlinerView* pOutlinerView,
368 std::vector<sd::SearchSelection>* pSelections);
370 /** Detect changes of the document or view and react accordingly. Such
371 changes may occur because different calls to
372 <member>SearchAndReplace()</member> there usually is user
373 interaction. This is at least the press of the search or replace
374 button but may include any other action some of which affect the
375 search.
377 void DetectChange();
379 /** Detect whether the selection has changed.
380 @return
381 Return <TRUE/> when the selection has been changed since the
382 last call to this method.
384 bool DetectSelectionChange();
386 /** Remember the current edited object/caret position/page/view mode
387 when starting to search/spell check so that it can be restored on
388 termination.
390 void RememberStartPosition();
392 /** Restore the position stored in the last call of
393 <member>RememberStartPositiony</member>.
395 void RestoreStartPosition();
397 /** Provide next object to search or spell check as text object in edit
398 mode on the current page. This skips all objects that do not
399 match or are no text object.
401 void ProvideNextTextObject();
403 /** Handle the situation that the iterator has reached the last object.
404 This may result in setting the <member>mbEndOfSearch</member> flag
405 back to </sal_False>. This method may show either the end-of-search
406 dialog or the wrap-around dialog.
408 void EndOfSearch();
410 /** Show a dialog that tells the user that the search has ended either
411 because there are no more matches after finding at least one or that
412 no match has been found at all.
414 void ShowEndOfSearchDialog();
416 /** Show a dialog that asks the user whether to wrap around to the
417 beginning/end of the document and continue with the search/spell
418 check.
420 bool ShowWrapAroundDialog();
422 /** Put text of current text object into outliner so that the text can
423 be searched/spell checked.
425 void PutTextIntoOutliner();
427 /** Prepare to do spell checking on the current text object. This
428 includes putting it into edit mode. Under certain conditions this
429 method sets <member>mbEndOfSearch</member> to <TRUE/>.
431 void PrepareSpellCheck();
433 /** Prepare to search and replace on the current text object. This
434 includes putting it into edit mode.
436 void PrepareSearchAndReplace();
438 /** Prepare to do a text conversion on the current text
439 object. This includes putting it into edit mode.
441 void PrepareConversion();
443 /** Switch to a new view mode. Try to restore the original edit mode
444 before doing so.
445 @param ePageKind
446 Specifies the new view mode.
448 void SetViewMode(PageKind ePageKind);
450 /** Switch to the page or master page specified by the
451 <member>mnPage</member> index. Master page mode is specified by
452 <member>meEditMode</member>.
453 @param eEditMode
454 The new edit mode.
455 @param nPageIndex
456 The new page index.
458 void SetPage(EditMode eEditMode, sal_uInt16 nPageIndex);
460 /** Switch on edit mode for the currently selected text object.
462 void EnterEditMode(bool bGrabFocus);
464 /** Return the position at which a new search is started with respect to
465 the search direction as specified by the argument.
466 @return
467 The position mentioned above in form of a selection with start
468 equals end.
470 ESelection GetSearchStartPosition() const;
472 /** Detect whether there exists a previous match. Note that only the
473 absence of such a match can be detected reliably. An existing match
474 is assumed when the search started not at the beginning/end of the
475 presentation. This does not have to be true. The user can have set
476 the cursor at the middle of the text without a prior search.
477 @return
478 Returns </True> when there is no previous match and </False>
479 when there may be one.
481 bool HasNoPreviousMatch();
483 /** Handle a failed search (with or without replace) for the outline
484 mode. Show message boxes when the search failed completely,
485 i.e. there is no match in the whole presentation, or when no further
486 match exists.
487 @return
488 The returned value indicates whether another (wrapped around)
489 search shall take place. If that is so, then it is the caller's
490 responsibility to set the cursor position accordingly.
492 bool HandleFailedSearch();
494 /** Take a position as returned by an object iterator and switch to the
495 view and page on which the object specified by this position is
496 located.
497 @param rPosition
498 This position points to a <type>SdrObject</type> object and
499 contains the view and page where it is located.
500 @return
501 Return a pointer to the <type>SdrObject</type>.
503 SdrObject* SetObject(const ::sd::outliner::IteratorPosition& rPosition);
505 /** Use this method when the view shell in which to search has changed.
506 It handles i.e. registering at the associated view as selection
507 change listener.
509 void SetViewShell(const std::shared_ptr<::sd::ViewShell>& rpViewShell);
511 /** Activate or deactivate the search in the current selection. Call
512 this method whenever the selection has changed. This method creates
513 a copy of the current selection and reassigns the object iterator to
514 the current() iterator.
516 void HandleChangedSelection();
518 /** Initiate the spell check of the next relevant text object.
519 When the outline view is active then this method is called
520 after a wrap around to continue at the beginning of the document.
521 @return
522 Returns <TRUE/> to indicate that another call to this method is
523 required. When all text objects have been processed then
524 <FALSE/> is returned.
526 virtual bool SpellNextDocument() override;
528 /** Find the right parent to use for a message. This function makes sure
529 that the otherwise non-modal search or spell dialogs, if visible, are
530 locked, too.
532 weld::Window* GetMessageBoxParent();
535 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */