Line data Source code
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 :
20 : #ifndef INCLUDED_SD_INC_OUTLINER_HXX
21 : #define INCLUDED_SD_INC_OUTLINER_HXX
22 :
23 : #include <svx/svdobj.hxx>
24 : #include <svx/svdoutl.hxx>
25 : #include "pres.hxx"
26 : #include "OutlinerIterator.hxx"
27 : #include <editeng/SpellPortions.hxx>
28 : #include <memory>
29 : #include <boost/shared_ptr.hpp>
30 : #include <boost/weak_ptr.hpp>
31 : #include <boost/noncopyable.hpp>
32 :
33 : class Dialog;
34 : class SdrObject;
35 : class SdrTextObj;
36 : class SdDrawDocument;
37 :
38 : namespace sd {
39 :
40 : class View;
41 : class ViewShell;
42 : class Window;
43 :
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.
48 :
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>
53 :
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
58 : object.<br>
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:
63 : <ol>
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>
70 : </ol>
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
77 : direction).</p>
78 :
79 : <p>The start position is restored after finishing spell checking or
80 : replacing all matches in a document.</p>
81 :
82 : <p>Some related pieces of information:
83 : The search dialog (<type>SvxSearchDialog</type>) can be controlled in
84 : more than one way:
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.
94 : </p>
95 : */
96 : class Outliner
97 : : public SdrOutliner,
98 : public ::boost::noncopyable
99 : {
100 : public:
101 : friend class ::sd::outliner::OutlinerContainer;
102 :
103 : /** Create a new sd outliner object.
104 : @param pDoc
105 : The draw document from which to take the content.
106 : @param nMode
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.
113 : */
114 : Outliner( SdDrawDocument* pDoc, sal_uInt16 nMode );
115 : virtual ~Outliner();
116 :
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
121 : checking.
122 : */
123 : void PrepareSpelling();
124 :
125 : /** Initialize a spell check but do not start it yet. This method
126 : is a better candidate for the name PrepareSpelling.
127 : */
128 : void StartSpelling();
129 :
130 : /** Proxy for method from base class to avoid compiler warning */
131 : void StartSpelling(EditView&, unsigned char);
132 :
133 : /** Initiate a find and/or replace on the next relevant text object.
134 : @return
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.
138 : */
139 : bool StartSearchAndReplace (const SvxSearchItem* pSearchItem);
140 :
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.
144 : */
145 : svx::SpellPortions GetNextSpellSentence();
146 :
147 : /** Release all resources that have been created during the find&replace
148 : or spell check.
149 : */
150 : void EndSpelling();
151 :
152 : /** callback for textconversion */
153 : bool ConvertNextDocument() SAL_OVERRIDE;
154 :
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 );
159 :
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.
163 : */
164 : void BeginConversion();
165 :
166 : /** Release all resources that have been created during the conversion */
167 : void EndConversion();
168 :
169 : DECL_LINK( SpellError, void * );
170 :
171 : enum ChangeHint { CH_VIEW_SHELL_INVALID, CH_VIEW_SHELL_VALID };
172 :
173 0 : int GetIgnoreCurrentPageChangesLevel() const { return mnIgnoreCurrentPageChangesLevel; };
174 0 : void IncreIgnoreCurrentPageChangesLevel() { mnIgnoreCurrentPageChangesLevel++; };
175 0 : void DecreIgnoreCurrentPageChangesLevel() { mnIgnoreCurrentPageChangesLevel--; };
176 :
177 : private:
178 : class Implementation;
179 : ::std::unique_ptr<Implementation> mpImpl;
180 :
181 : /// Specifies whether to search and replace, to spell check or to do a
182 : /// text conversion.
183 : enum mode {SEARCH, SPELL, TEXT_CONVERSION} meMode;
184 :
185 : /// The view which displays the searched objects.
186 : ::sd::View* mpView;
187 : /** The view shell containing the view. It is held as weak
188 : pointer to avoid keeping it alive when the view is changed
189 : during searching.
190 : */
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;
196 :
197 : /** this is the language that is used for current text conversion.
198 : Only valid if meMode is TEXT_CONVERSION.
199 : */
200 : sal_Int16 mnConversionLanguage;
201 :
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.
204 : */
205 : int mnIgnoreCurrentPageChangesLevel;
206 :
207 : /// Specifies whether the search string has been found so far.
208 : bool mbStringFound;
209 :
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.
215 : */
216 : bool mbMatchMayExist;
217 :
218 : /// The number of pages in the current view.
219 : sal_uInt16 mnPageCount;
220 :
221 : /// Number of objects on the current page / in the current selection.
222 : sal_Int32 mnObjectCount;
223 :
224 : /** A <TRUE/> value indicates that the end of the find&replace or spell
225 : check has been reached.
226 : */
227 : bool mbEndOfSearch;
228 :
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>.
232 : */
233 : bool mbFoundObject;
234 :
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
237 : check.
238 : */
239 : bool mbError;
240 :
241 : /** This flag indicates whether to search forward or backwards.
242 : */
243 : bool mbDirectionIsForward;
244 :
245 : /** This flag indicates that only the selected objects are to be
246 : searched.
247 : */
248 : bool mbRestrictSearchToSelection;
249 :
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.
254 : */
255 : ::std::vector<SdrObjectWeakRef> maMarkListCopy;
256 :
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.
260 : */
261 : bool mbProcessCurrentViewOnly;
262 :
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
267 : objects.
268 : */
269 : SdrObject* mpObj;
270 :
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.
274 : */
275 : SdrObject* mpFirstObj;
276 :
277 : /// Candidate for being searched/spell checked.
278 : SdrTextObj* mpTextObj;
279 :
280 : /// Current text to be searched/spelled inside the current text object
281 : sal_Int32 mnText;
282 :
283 : /// Paragraph object of <member>mpTextObj</member>.
284 : OutlinerParaObject* mpParaObj;
285 :
286 : /// The view mode that was active when starting to search/spell check.
287 : PageKind meStartViewMode;
288 :
289 : /// The master page mode that was active when starting to search/spell check.
290 : EditMode meStartEditMode;
291 :
292 : /// The current page index on starting to search/spell check.
293 : sal_uInt16 mnStartPageIndex;
294 :
295 : /// The object in edit mode when searching /spell checking was started
296 : /// (if any).
297 : SdrObject* mpStartEditedObject;
298 :
299 : /// The position of the caret when searching /spell checking was started.
300 : ESelection maStartSelection;
301 :
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.
305 : */
306 : const SvxSearchItem* mpSearchItem;
307 :
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.
318 : */
319 : ::sd::outliner::IteratorPosition maLastValidPosition;
320 :
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.
324 : */
325 : bool mbSelectionHasChanged;
326 :
327 : /** This flag indicates whether a selection change event is expected due
328 : to a programatical change of the selection.
329 : */
330 : bool mbExpectingSelectionChangeEvent;
331 :
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.
335 : */
336 : bool mbWholeDocumentProcessed;
337 :
338 : /** When this flag is true then a PrepareSpelling() is executed when
339 : StartSearchAndReplace() is called the next time.
340 : */
341 : bool mbPrepareSpellingPending;
342 :
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
351 : is reversed.
352 : */
353 : void Initialize (bool bDirectionIsForward);
354 :
355 : /** Do search and replace for whole document.
356 : */
357 : bool SearchAndReplaceAll();
358 :
359 : /** Do search and replace for next match.
360 : @return
361 : The return value specifies whether the search ended (</sal_True>) or
362 : another call to this method is required (</sal_False>).
363 : */
364 : bool SearchAndReplaceOnce();
365 :
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
371 : search.
372 : */
373 : void DetectChange();
374 :
375 : /** Detect whether the selection has changed.
376 : @return
377 : Return <TRUE/> when the selection has been changed since the
378 : last call to this method.
379 : */
380 : bool DetectSelectionChange();
381 :
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
384 : termination.
385 : */
386 : void RememberStartPosition();
387 :
388 : /** Restore the position stored in the last call of
389 : <member>RememberStartPositiony</member>.
390 : */
391 : void RestoreStartPosition();
392 :
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.
396 : */
397 : void ProvideNextTextObject();
398 :
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.
403 : */
404 : void EndOfSearch();
405 :
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.
409 : */
410 : void ShowEndOfSearchDialog();
411 :
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
414 : check.
415 : */
416 : bool ShowWrapArroundDialog();
417 :
418 : /** Check whether the object pointed to by the iterator is a valid text
419 : object.
420 : @param aPosition
421 : The object for which to test whether it is a valid text object.
422 : */
423 : static bool IsValidTextObject (const ::sd::outliner::IteratorPosition& rPosition);
424 :
425 : /** Put text of current text object into outliner so that the text can
426 : be searched/spell checked.
427 : */
428 : void PutTextIntoOutliner();
429 :
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/>.
433 : */
434 : void PrepareSpellCheck();
435 :
436 : /** Prepare to search and replace on the current text object. This
437 : includes putting it into edit mode.
438 : */
439 : void PrepareSearchAndReplace();
440 :
441 : /** Prepare to do a text conversion on the current text
442 : object. This includes putting it into edit mode.
443 : */
444 : void PrepareConversion();
445 :
446 : /** Switch to a new view mode. Try to restore the original edit mode
447 : before doing so.
448 : @param ePageKind
449 : Specifies the new view mode.
450 : */
451 : void SetViewMode (PageKind ePageKind);
452 :
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>.
456 : @param eEditMode
457 : The new edit mode.
458 : @param nPageIndex
459 : The new page index.
460 : */
461 : void SetPage (EditMode eEditMode, sal_uInt16 nPageIndex);
462 :
463 : /** Switch on edit mode for the currently selected text object.
464 : */
465 : void EnterEditMode (bool bGrabFocus=true);
466 :
467 : /** Return the position at which a new search is started with respect to
468 : the search direction as specified by the argument.
469 : @return
470 : The position mentioned above in form of a selection with start
471 : equals end.
472 : */
473 : ESelection GetSearchStartPosition();
474 :
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.
480 : @return
481 : Returns </True> when there is no previous match and </False>
482 : when there may be one.
483 : */
484 : bool HasNoPreviousMatch();
485 :
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
489 : match exists.
490 : @return
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.
494 : */
495 : bool HandleFailedSearch();
496 :
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
499 : located.
500 : @param rPosition
501 : This position points to a <type>SdrObject</type> object and
502 : contains the view and page where it is located.
503 : @return
504 : Return a pointer to the <type>SdrObject</type>.
505 : */
506 : SdrObject* SetObject (const ::sd::outliner::IteratorPosition& rPosition);
507 :
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
510 : change listener.
511 : */
512 : void SetViewShell (const ::boost::shared_ptr<ViewShell>& rpViewShell);
513 :
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.
518 : */
519 : void HandleChangedSelection();
520 :
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.
524 : @return
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.
528 : */
529 : virtual bool SpellNextDocument() SAL_OVERRIDE;
530 :
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.
535 : */
536 : sal_uInt16 ShowModalMessageBox (Dialog& rMessageBox);
537 : };
538 :
539 : } // end of namespace sd
540 :
541 : #endif
542 :
543 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|