1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 #ifndef INCLUDED_SD_INC_OUTLINER_HXX
21 #define INCLUDED_SD_INC_OUTLINER_HXX
23 #include <svx/svdobj.hxx>
24 #include <svx/svdoutl.hxx>
26 #include "OutlinerIterator.hxx"
27 #include <editeng/SpellPortions.hxx>
29 #include <boost/shared_ptr.hpp>
30 #include <boost/weak_ptr.hpp>
31 #include <boost/noncopyable.hpp>
44 /** The main purpose of this class is searching and replacing as well as
45 spelling of impress documents. The main part of both tasks lies in
46 iterating over the pages and view modes of a document and apply the
47 respective function to all objects containing text on those pages.
49 <p>Relevant objects: There are two sets of objects to search/spell
50 check. One is the set of all selected objects. The other consists of
51 all objects on all pages in draw-, notes-, and handout view as well as
52 slide- and background view (draw pages and master pages).</p>
54 <p>Iteration: Search/replace and spelling functions operate on shapes
55 containing text. To cover all relevant objects an order has to be
56 defined on the objects. For the set of all selected objects this order
57 is simply the order in which they can be retrieved from the selection
59 When there is no selection the order is nested. The three modes of the
60 draw view are on the outer level: draw mode, notes mode, handout mode.
61 The inner level switches between draw pages and master pages. This
62 leads to the following order:
64 <li>draw pages of draw mode</li>
65 <li>master pages of draw mode</li>
66 <li>draw pages of notes mode</li>
67 <li>master pages of notes mode</li>
68 <li>draw pages of handout mode</li>
69 <li>master pages of handout mode</li>
71 Iteration starts at the top of the current page. When reaching the end
72 of the document, i.e. the last master page of the handout mode, it jumps
73 to the first draw page of draw mode. In backward searches this order is
74 reversed. When doing a <em>replace all</em> then the whole document is
75 searched for matches starting at the first page of the draw/slide view
76 (or last page of handout/background view even though search
79 <p>The start position is restored after finishing spell checking or
80 replacing all matches in a document.</p>
82 <p>Some related pieces of information:
83 The search dialog (<type>SvxSearchDialog</type>) can be controlled in
85 <ul><li>A set of option flags returned by the slot call
86 SID_SEARCH_OPTIONS handled by the
87 <member>SdDrawDocument::GetState()</member> method.</li>
88 <li>The contents of the search item of type
89 <type>SvxSearchItem</type>.</li>
90 <li>The <member>HasSelection()</member> view shell method that returns
91 whether or not a selection exists. However, it is called from the
92 search dialog with an argument so that only text selections are
93 queried. This is only sufficient for searching the outline view.
98 public ::boost::noncopyable
101 friend class ::sd::outliner::OutlinerContainer
;
103 /** Create a new sd outliner object.
105 The draw document from which to take the content.
107 The valid values <const>OUTLINERMODE_DONTKNOW</const>,
108 <const>OUTLINERMODE_TEXTOBJECT</const>,
109 <const>OUTLINERMODE_TITLEOBJECT</const>,
110 <const>OUTLINERMODE_OUTLINEOBJECT</const>, and
111 <const>OUTLINERMODE_OUTLINEVIEW</const> are defined in
112 editeng/outliner.hxx.
114 Outliner( SdDrawDocument
* pDoc
, sal_uInt16 nMode
);
117 /** Despite the name this method is called prior to spell checking *and*
118 searching and replacing. The position of current view
119 mode/page/object/caret position is remembered and, depending on the
120 search mode, may be restored after finishing searching/spell
123 void PrepareSpelling();
125 /** Initialize a spell check but do not start it yet. This method
126 is a better candidate for the name PrepareSpelling.
128 void StartSpelling();
130 /** Proxy for method from base class to avoid compiler warning */
131 void StartSpelling(EditView
&, unsigned char);
133 /** Initiate a find and/or replace on the next relevant text object.
135 Returns </sal_True> when the search/replace is finished (as
136 indicated by user input to the search dialog). A </sal_False> value
137 indicates that another call to this method is required.
139 bool StartSearchAndReplace (const SvxSearchItem
* pSearchItem
);
141 /** Iterate over the sentences in all text shapes and stop at the
142 next sentence with spelling errors. While doing so the view
143 mode may be changed and text shapes are set into edit mode.
145 svx::SpellPortions
GetNextSpellSentence();
147 /** Release all resources that have been created during the find&replace
152 /** callback for textconversion */
153 bool ConvertNextDocument() SAL_OVERRIDE
;
155 /** Starts the text conversion (hangul/hanja or Chinese simplified/traditional)
156 for the current viewshell */
157 void StartConversion( sal_Int16 nSourceLanguage
, sal_Int16 nTargetLanguage
,
158 const vcl::Font
*pTargetFont
, sal_Int32 nOptions
, bool bIsInteractive
);
160 /** This is called internally when text conversion is started.
161 The position of current view mode/page/object/caret position
162 is remembered and will be restored after conversion.
164 void BeginConversion();
166 /** Release all resources that have been created during the conversion */
167 void EndConversion();
169 DECL_LINK( SpellError
, void * );
171 enum ChangeHint
{ CH_VIEW_SHELL_INVALID
, CH_VIEW_SHELL_VALID
};
173 int GetIgnoreCurrentPageChangesLevel() const { return mnIgnoreCurrentPageChangesLevel
; };
174 void IncreIgnoreCurrentPageChangesLevel() { mnIgnoreCurrentPageChangesLevel
++; };
175 void DecreIgnoreCurrentPageChangesLevel() { mnIgnoreCurrentPageChangesLevel
--; };
178 class Implementation
;
179 ::std::unique_ptr
<Implementation
> mpImpl
;
181 /// Specifies whether to search and replace, to spell check or to do a
183 enum mode
{SEARCH
, SPELL
, TEXT_CONVERSION
} meMode
;
185 /// The view which displays the searched objects.
187 /** The view shell containing the view. It is held as weak
188 pointer to avoid keeping it alive when the view is changed
191 ::boost::weak_ptr
<ViewShell
> mpWeakViewShell
;
192 /// This window contains the view.
193 VclPtr
< ::sd::Window
> mpWindow
;
194 /// The document on whose objects and pages this class operates.
195 SdDrawDocument
* mpDrawDocument
;
197 /** this is the language that is used for current text conversion.
198 Only valid if meMode is TEXT_CONVERSION.
200 sal_Int16 mnConversionLanguage
;
202 /** While the value of this flag is greater than 0 changes of the current page
203 do not lead to selecting the corresponding text in the outliner.
205 int mnIgnoreCurrentPageChangesLevel
;
207 /// Specifies whether the search string has been found so far.
210 /** This flag indicates whether there may exist a match of the search
211 string before/after the current position in the document. It can be
212 set to </sal_False> only when starting from the beginning/end of the
213 document. When reaching the end/beginning with it still be set to
214 </sal_False> then there exists no match and the search can be terminated.
216 bool mbMatchMayExist
;
218 /// The number of pages in the current view.
219 sal_uInt16 mnPageCount
;
221 /// Number of objects on the current page / in the current selection.
222 sal_Int32 mnObjectCount
;
224 /** A <TRUE/> value indicates that the end of the find&replace or spell
225 check has been reached.
229 /** Set to <TRUE/> when an object has been prepared successfully for
230 searching/spell checking. This flag directs the internal iteration
231 which stops when set to </sal_True>.
235 /** When set to <TRUE/> this flag indicates that an error has occurred
236 that should terminate the iteration over the objects to search/spell
241 /** This flag indicates whether to search forward or backwards.
243 bool mbDirectionIsForward
;
245 /** This flag indicates that only the selected objects are to be
248 bool mbRestrictSearchToSelection
;
250 /** When the search is restricted to the current selection then
251 this list contains pointers to all the objects of the
252 selection. This copy is necessary because during the search
253 process the mark list is modified.
255 ::std::vector
<SdrObjectWeakRef
> maMarkListCopy
;
257 /** This flag indicates that only the current view is to be used for
258 searching and spelling. Automatically switching to other view does
259 not take place when this flag is set.
261 bool mbProcessCurrentViewOnly
;
263 /** Current object that may be a text object. The object pointer to
264 corresponds to <member>mnObjIndex</member>. While iterating over the
265 objects on a page <member>mpObj</member> will point to every object
266 while <member>mpTextObj</member> will be set only to valid text
271 /** this stores the first object that is used for text conversion.
272 Conversion automatically wraps around the document and stops when it
273 finds this object again.
275 SdrObject
* mpFirstObj
;
277 /// Candidate for being searched/spell checked.
278 SdrTextObj
* mpTextObj
;
280 /// Current text to be searched/spelled inside the current text object
283 /// Paragraph object of <member>mpTextObj</member>.
284 OutlinerParaObject
* mpParaObj
;
286 /// The view mode that was active when starting to search/spell check.
287 PageKind meStartViewMode
;
289 /// The master page mode that was active when starting to search/spell check.
290 EditMode meStartEditMode
;
292 /// The current page index on starting to search/spell check.
293 sal_uInt16 mnStartPageIndex
;
295 /// The object in edit mode when searching /spell checking was started
297 SdrObject
* mpStartEditedObject
;
299 /// The position of the caret when searching /spell checking was started.
300 ESelection maStartSelection
;
302 /** The search item contains various attributes that define the type of
303 search. It is set every time the
304 <member>SearchAndReplaceAll</member> method is called.
306 const SvxSearchItem
* mpSearchItem
;
308 /// The actual object iterator.
309 ::sd::outliner::Iterator maObjectIterator
;
310 /// The current position of the object iterator.
311 ::sd::outliner::IteratorPosition maCurrentPosition
;
312 /// The position when the search started. Corresponds largely to the
313 /// m?Start* members.
314 ::sd::outliner::Iterator maSearchStartPosition
;
315 /** The last valid position describes where the last text object has been
316 found. This position is restored when some dialogs are shown. The
317 position is initially set to the where the search begins.
319 ::sd::outliner::IteratorPosition maLastValidPosition
;
321 /** This flag remembers a selection change between a call to the
322 selection change listener callback and the next
323 <member>DetectChange()</member> method call.
325 bool mbSelectionHasChanged
;
327 /** This flag indicates whether a selection change event is expected due
328 to a programatical change of the selection.
330 bool mbExpectingSelectionChangeEvent
;
332 /** This flag is set to true when the whole document has been
333 processed once 'officially', i.e. a message box has been shown
334 that tells the user so.
336 bool mbWholeDocumentProcessed
;
338 /** When this flag is true then a PrepareSpelling() is executed when
339 StartSearchAndReplace() is called the next time.
341 bool mbPrepareSpellingPending
;
343 /** Initialize the object iterator. Call this method after being
344 invoked from the search or spellcheck dialog. It creates a new
345 iterator pointing at the current object when this has not been done
346 before. It reverses the direction of iteration if the given flag
347 differs from the current direction.
348 @param bDirectionIsForward
349 This flag specifies in which direction to iterator over the
350 objects. If it differs from the current direction the iterator
353 void Initialize (bool bDirectionIsForward
);
355 /** Do search and replace for whole document.
357 bool SearchAndReplaceAll();
359 /** Do search and replace for next match.
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();
366 /** Detect changes of the document or view and react accordingly. Such
367 changes may occur because different calls to
368 <member>SearchAndReplace()</member> there usually is user
369 interaction. This is at least the press of the search or replace
370 button but may include any other action some of which affect the
375 /** Detect whether the selection has changed.
377 Return <TRUE/> when the selection has been changed since the
378 last call to this method.
380 bool DetectSelectionChange();
382 /** Remember the current edited object/caret position/page/view mode
383 when starting to search/spell check so that it can be restored on
386 void RememberStartPosition();
388 /** Restore the position stored in the last call of
389 <member>RememberStartPositiony</member>.
391 void RestoreStartPosition();
393 /** Provide next object to search or spell check as text object in edit
394 mode on the current page. This skips all objects that do not
395 match or are no text object.
397 void ProvideNextTextObject();
399 /** Handle the situation that the iterator has reached the last object.
400 This may result in setting the <member>mbEndOfSearch</member> flag
401 back to </sal_False>. This method may show either the end-of-search
402 dialog or the wrap-around dialog.
406 /** Show a dialog that tells the user that the search has ended either
407 because there are no more matches after finding at least one or that
408 no match has been found at all.
410 void ShowEndOfSearchDialog();
412 /** Show a dialog that asks the user whether to wrap around to the
413 beginning/end of the document and continue with the search/spell
416 bool ShowWrapArroundDialog();
418 /** Check whether the object pointed to by the iterator is a valid text
421 The object for which to test whether it is a valid text object.
423 static bool IsValidTextObject (const ::sd::outliner::IteratorPosition
& rPosition
);
425 /** Put text of current text object into outliner so that the text can
426 be searched/spell checked.
428 void PutTextIntoOutliner();
430 /** Prepare to do spell checking on the current text object. This
431 includes putting it into edit mode. Under certain conditions this
432 method sets <member>mbEndOfSearch</member> to <TRUE/>.
434 void PrepareSpellCheck();
436 /** Prepare to search and replace on the current text object. This
437 includes putting it into edit mode.
439 void PrepareSearchAndReplace();
441 /** Prepare to do a text conversion on the current text
442 object. This includes putting it into edit mode.
444 void PrepareConversion();
446 /** Switch to a new view mode. Try to restore the original edit mode
449 Specifies the new view mode.
451 void SetViewMode (PageKind ePageKind
);
453 /** Switch to the page or master page specified by the
454 <member>mnPage</member> index. Master page mode is specified by
455 <member>meEditMode</member>.
461 void SetPage (EditMode eEditMode
, sal_uInt16 nPageIndex
);
463 /** Switch on edit mode for the currently selected text object.
465 void EnterEditMode (bool bGrabFocus
=true);
467 /** Return the position at which a new search is started with respect to
468 the search direction as specified by the argument.
470 The position mentioned above in form of a selection with start
473 ESelection
GetSearchStartPosition();
475 /** Detect whether there exists a previous match. Note that only the
476 absence of such a match can be detected reliably. An existing match
477 is assumed when the search started not at the beginning/end of the
478 presentation. This does not have to be true. The user can have set
479 the cursor at the middle of the text without a prior search.
481 Returns </True> when there is no previous match and </False>
482 when there may be one.
484 bool HasNoPreviousMatch();
486 /** Handle a failed search (with or without replace) for the outline
487 mode. Show message boxes when the search failed completely,
488 i.e. there is no match in the whole presentation, or when no further
491 The returned value indicates whether another (wrapped around)
492 search shall take place. If that is so, then it is the caller's
493 responsibility to set the cursor position accordingly.
495 bool HandleFailedSearch();
497 /** Take a position as returned by an object iterator and switch to the
498 view and page on which the object specified by this position is
501 This position points to a <type>SdrObject</type> object and
502 contains the view and page where it is located.
504 Return a pointer to the <type>SdrObject</type>.
506 SdrObject
* SetObject (const ::sd::outliner::IteratorPosition
& rPosition
);
508 /** Use this method when the view shell in which to search has changed.
509 It handles i.e. registering at the associated view as selection
512 void SetViewShell (const ::boost::shared_ptr
<ViewShell
>& rpViewShell
);
514 /** Activate or deactivate the search in the current selection. Call
515 this method whenever the selection has changed. This method creates
516 a copy of the current selection and reassigns the object iterator to
517 the current() iterator.
519 void HandleChangedSelection();
521 /** Initiate the spell check of the next relevant text object.
522 When the outline view is active then this method is called
523 after a wrap around to continue at the beginning of the document.
525 Returns <TRUE/> to indicate that another call to this method is
526 required. When all text objects have been processed then
527 <FALSE/> is returned.
529 virtual bool SpellNextDocument() SAL_OVERRIDE
;
531 /** Show the given message box and make it modal. It is assumed that
532 the parent of the given dialog is NULL, i.e. the application
533 window. This function makes sure that the otherwise non-modal
534 search dialog, if visible, is locked, too.
536 sal_uInt16
ShowModalMessageBox (Dialog
& rMessageBox
);
539 } // end of namespace sd
543 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */