xref: /trunk/main/sd/inc/Outliner.hxx (revision 967189ef)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #ifndef SD_OUTLINER_HXX
29 #define SD_OUTLINER_HXX
30 
31 #include <svx/svdobj.hxx>
32 #include <svx/svdoutl.hxx>
33 #include "pres.hxx"
34 #include "OutlinerIterator.hxx"
35 #include <editeng/SpellPortions.hxx>
36 #include <memory>
37 #include <boost/shared_ptr.hpp>
38 #include <boost/weak_ptr.hpp>
39 #include <boost/noncopyable.hpp>
40 
41 class Dialog;
42 class SdPage;
43 class SdrObject;
44 class SdrTextObj;
45 class SdDrawDocument;
46 class SfxStyleSheetPool;
47 class SdrObjListIter;
48 
49 namespace sd {
50 
51 class DrawViewShell;
52 class View;
53 class ViewShell;
54 class Window;
55 
56 /** The main purpose of this class is searching and replacing as well as
57     spelling of impress documents.  The main part of both tasks lies in
58     iterating over the pages and view modes of a document and apply the
59     respective function to all objects containing text on those pages.
60 
61     <p>Relevant objects: There are two sets of objects to search/spell
62     check.  One is the set of all selected objects.  The other consists of
63     all objects on all pages in draw-, notes-, and handout view as well as
64     slide- and background view (draw pages and master pages).</p>
65 
66     <p>Iteration: Search/replace and spelling functions operate on shapes
67     containing text.  To cover all relevant objects an order has to be
68     defined on the objects.  For the set of all selected objects this order
69     is simply the order in which they can be retrieved from the selection
70     object.<br>
71     When there is no selection the order is nested.  The three modes of the
72     draw view are on the outer level: draw mode, notes mode, handout mode.
73     The inner level switches between draw pages and master pages.  This
74     leads to the following order:
75     <ol>
76     <li>draw pages of draw mode</li>
77     <li>master pages of draw mode</li>
78     <li>draw pages of notes mode</li>
79     <li>master pages of notes mode</li>
80     <li>draw pages of handout mode</li>
81     <li>master pages of handout mode</li>
82     </ol>
83     Iteration starts at the top of the current page.  When reaching the end
84     of the document, i.e. the last master page of the handout mode, it jumps
85     to the first draw page of draw mode.  In backward searches this order is
86     reversed.  When doing a <em>replace all</em> then the whole document is
87     searched for matches starting at the first page of the draw/slide view
88     (or last page of handout/background view even though search
89     direction).</p>
90 
91     <p>The start position is restored after finishing spell checking or
92     replacing all matches in a document.</p>
93 
94     <p>Some related pieces of information:
95     The search dialog (<type>SvxSearchDialog</type>) can be controlled in
96     more than one way:
97     <ul><li>A set of option flags returned by the slot call
98     SID_SEARCH_OPTIONS handled by the
99     <member>SdDrawDocument::GetState()</member> method.</li>
100     <li>The contents of the search item of type
101     <type>SvxSearchItem</type>.</li>
102     <li>The <member>HasSelection()</member> view shell method that returns
103     whether or not a selection exists.  However, it is called from the
104     search dialog with an argument so that only text selections are
105     queried.  This is only sufficient for searching the outline view.
106     </p>
107 */
108 class Outliner
109     : public SdrOutliner,
110       public ::boost::noncopyable
111 {
112 public:
113     friend class ::sd::outliner::OutlinerContainer;
114 
115     /** Create a new sd outliner object.
116         @param pDoc
117             The draw document from which to take the content.
118         @param nMode
119             The valid values <const>OUTLINERMODE_DONTKNOW</const>,
120             <const>OUTLINERMODE_TEXTOBJECT</const>,
121             <const>OUTLINERMODE_TITLEOBJECT</const>,
122             <const>OUTLINERMODE_OUTLINEOBJECT</const>, and
123             <const>OUTLINERMODE_OUTLINEVIEW</const> are defined in
124             editeng/outliner.hxx.
125     */
126 	Outliner( SdDrawDocument* pDoc, sal_uInt16 nMode );
127 	virtual ~Outliner();
128 
129 	/** Despite the name this method is called prior to spell cheking *and*
130         searching and replacing.  The position of current view
131         mode/page/object/caret position is remembered and, depending on the
132         search mode, may be restored after finishing searching/spell
133         checking.
134     */
135 	void PrepareSpelling (void);
136 
137     /** Initialize a spell check but do not start it yet.  This method
138         is a better candiate for the name PrepareSpelling.
139     */
140     void StartSpelling (void);
141 
142 	/** Proxy for method from base class to avoid compiler warning */
143 	void StartSpelling(EditView&, unsigned char);
144 
145 	/** Initiate a find and/or replace on the next relevant text object.
146         @return
147             Returns </sal_True> when the search/replace is finished (as
148             indicated by user input to the search dialog).  A </sal_False> value
149             indicates that another call to this method is required.
150     */
151     bool StartSearchAndReplace (const SvxSearchItem* pSearchItem);
152 
153     /** Iterate over the sentences in all text shapes and stop at the
154         next sentence with spelling errors. While doing so the view
155         mode may be changed and text shapes are set into edit mode.
156     */
157     ::svx::SpellPortions GetNextSpellSentence (void);
158 
159     /** Release all resources that have been created during the find&replace
160         or spell check.
161     */
162 	void EndSpelling (void);
163 
164     /** callback for textconversion */
165 	sal_Bool ConvertNextDocument (void);
166 
167     /** Starts the text conversion (hangul/hanja or Chinese simplified/traditional)
168     for the current viewshell */
169     void StartConversion( sal_Int16 nSourceLanguage,  sal_Int16 nTargetLanguage,
170                 const Font *pTargetFont, sal_Int32 nOptions, sal_Bool bIsInteractive );
171 
172     /** This is called internaly when text conversion is started.
173 		The position of current view mode/page/object/caret position
174 		is remembered and will be restored after conversion.
175     */
176 	void BeginConversion (void);
177 
178 	/** Release all resources that have been created during the conversion */
179 	void EndConversion (void);
180 
181 	DECL_LINK( SpellError, void * );
182 
183     enum ChangeHint { CH_VIEW_SHELL_INVALID, CH_VIEW_SHELL_VALID };
184 
185 	int         GetIgnoreCurrentPageChangesLevel() const	 { return mnIgnoreCurrentPageChangesLevel; };
186 	void        IncreIgnoreCurrentPageChangesLevel()	 { mnIgnoreCurrentPageChangesLevel++; };
187 	void        DecreIgnoreCurrentPageChangesLevel()	 { mnIgnoreCurrentPageChangesLevel--; };
188 
189 private:
190     class Implementation;
191     ::std::auto_ptr<Implementation> mpImpl;
192 
193     /// Specifies whether to search and replace, to spell check or to do a
194     /// text conversion.
195     enum mode {SEARCH, SPELL, TEXT_CONVERSION} meMode;
196 
197     /// The view which displays the searched objects.
198 	::sd::View* mpView;
199     /** The view shell containing the view.  It is held as weak
200         pointer to avoid keeping it alive when the view is changed
201         during searching.
202     */
203     ::boost::weak_ptr<ViewShell> mpWeakViewShell;
204     /// This window contains the view.
205 	::sd::Window* mpWindow;
206     /// The document on whose objects and pages this class operates.
207 	SdDrawDocument* mpDrawDocument;
208 
209 	/** this is the language that is used for current text conversion.
210         Only valid if meMode is TEXT_CONVERSION.
211 	*/
212 	sal_Int16 mnConversionLanguage;
213 
214 	/** While the value of this flag is greater than 0 changes of the current page
215         do not lead to selecting the corresponding text in the outliner.
216     */
217     int mnIgnoreCurrentPageChangesLevel;
218 
219     /// Specifies whether the search string has been found so far.
220     bool mbStringFound;
221 
222     /** This flag indicates whether there may exist a match of the search
223         string before/after the current position in the document.  It can be
224         set to </sal_False> only when starting from the beginning/end of the
225         document.  When reaching the end/beginning with it still be set to
226         </sal_False> then there exists no match and the search can be terminated.
227     */
228     bool mbMatchMayExist;
229 
230     /// The number of pages in the current view.
231 	sal_uInt16 mnPageCount;
232 
233     /// Number of objects on the current page / in the current selection.
234 	sal_Int32 mnObjectCount;
235 
236     /** A <TRUE/> value indicates that the end of the find&replace or spell
237         check has been reached.
238     */
239     bool mbEndOfSearch;
240 
241     /** Set to <TRUE/> when an object has been prepared successfully for
242         searching/spell checking.  This flag directs the internal iteration
243         which stops when set to </sal_True>.
244     */
245     bool mbFoundObject;
246 
247     /** When set to <TRUE/> this flag indicates that an error has occured
248         that should terminate the iteration over the objects to search/spell
249         check.
250     */
251     bool mbError;
252 
253     /** This flag indicates whether to search forward or backwards.
254     */
255     bool mbDirectionIsForward;
256 
257     /** This flag indicates that only the selected objects are to be
258         searched.
259     */
260     bool mbRestrictSearchToSelection;
261 
262     /** When the search is restricted to the current selection then
263         this list contains pointers to all the objects of the
264         selection.  This copy is necessary because during the search
265         process the mark list is modified.
266     */
267     ::std::vector<SdrObjectWeakRef> maMarkListCopy;
268 
269     /**  This flag inidcates that only the current view is to be used for
270          searching and spelling.  Automatically switching to other view does
271          not take place when this flag is set.
272     */
273     bool mbProcessCurrentViewOnly;
274 
275     /** Current object that may be a text object.  The object pointer to
276         corresponds to <member>mnObjIndex</member>.  While iterating over the
277         objects on a page <member>mpObj</member> will point to every object
278         while <member>mpTextObj</member> will be set only to valid text
279         objects.
280     */
281 	SdrObject* mpObj;
282 
283     /** this stores the first object that is used for text conversion.
284 		Conversion automaticly wraps around the document and stops when it
285 		finds this object again.
286 	*/
287 	SdrObject* mpFirstObj;
288 
289     /// Candidate for being searched/spell checked.
290 	SdrTextObj* mpTextObj;
291 
292 	/// Current text to be searched/spelled inside the current text object
293 	sal_Int32 mnText;
294 
295     /// Paragraph object of <member>mpTextObj</member>.
296 	OutlinerParaObject* mpParaObj;
297 
298     /// The view mode that was active when starting to search/spell check.
299     PageKind meStartViewMode;
300 
301     /// The master page mode that was active when starting to search/spell check.
302 	EditMode meStartEditMode;
303 
304     /// The current page index on starting to search/spell check.
305 	sal_uInt16 mnStartPageIndex;
306 
307     /// The object in edit mode when searching /spell checking was started
308     /// (if any).
309 	SdrObject* mpStartEditedObject;
310 
311     /// The position of the caret when searching /spell checking was started.
312     ESelection maStartSelection;
313 
314     /** The search item contains various attributes that define the type of
315         search.  It is set every time the
316         <member>SearchAndReplaceAll</member> method is called.
317     */
318     const SvxSearchItem* mpSearchItem;
319 
320     /// The actual object iterator.
321     ::sd::outliner::Iterator maObjectIterator;
322     /// The current position of the object iterator.
323     ::sd::outliner::IteratorPosition maCurrentPosition;
324     /// The position when the search started.  Corresponds largely to the
325     /// m?Start* members.
326     ::sd::outliner::Iterator maSearchStartPosition;
327     /** The last valid position desribes where the last text object has been
328         found.  This position is restored when some dialogs are shown.  The
329         position is initially set to the where the search begins.
330     */
331     ::sd::outliner::IteratorPosition maLastValidPosition;
332 
333     /** This flag remebers a selection change between a call to the
334         selection change listener callback and the next
335         <member>DetectChange()</member> method call.
336     */
337     bool mbSelectionHasChanged;
338 
339     /** This flag indicates whether a selection change event is expected due
340         to a programatical change of the selection.
341     */
342     bool mbExpectingSelectionChangeEvent;
343 
344     /** This flag is set to true when the whole document has been
345         processed once 'officially', i.e. a message box has been shown
346         that tells the user so.
347     */
348     bool mbWholeDocumentProcessed;
349 
350     /** When this flag is true then a PrepareSpelling() is executed when
351         StartSearchAndReplace() is called the next time.
352     */
353     bool mbPrepareSpellingPending;
354 
355     /** Initialize the object iterator.  Call this method after being
356         invoked from the search or spellcheck dialog.  It creates a new
357         iterator pointing at the current object when this has not been done
358         before.  It reverses the direction of iteration if the given flag
359         differs from the current direction.
360         @param bDirectionIsForward
361             This flag specifies in which direction to iterator over the
362             objects.  If it differs from the current direction the iterator
363             is reversed.
364     */
365     void Initialize (bool bDirectionIsForward);
366 
367     /** Do search and replace for whole document.
368     */
369     bool SearchAndReplaceAll (void);
370 
371     /** Do search and replace for next match.
372         @return
373             The return value specifies whether the search ended (</sal_True>) or
374             another call to this method is required (</sal_False>).
375     */
376     bool SearchAndReplaceOnce (void);
377 
378     /** Detect changes of the document or view and react accordingly.  Such
379         changes may occur because different calls to
380         <member>SearchAndReplace()</member> there usually is user
381         interaction.  This is at least the press of the search or replace
382         button but may include any other action some of which affect the
383         search.
384     */
385     void DetectChange (void);
386 
387     /** Detect whether the selection has changed.
388         @return
389             Return <TRUE/> when the selection has been changed since the
390             last call to this method.
391     */
392     bool DetectSelectionChange (void);
393 
394     /** Remember the current edited object/caret position/page/view mode
395         when starting to search/spell check so that it can be restored on
396         termination.
397     */
398     void RememberStartPosition (void);
399 
400     /** Restore the position stored in the last call of
401         <member>RememberStartPositiony</member>.
402     */
403     void RestoreStartPosition (void);
404 
405     /** Provide next object to search or spell check as text object in edit
406         mode on the current page.  This skips all objects that do not
407         match or are no text object.
408     */
409     void ProvideNextTextObject (void);
410 
411     /** Handle the situation that the iterator has reached the last object.
412         This may result in setting the <member>mbEndOfSearch</member> flag
413         back to </sal_False>.  This method may show either the end-of-search
414         dialog or the wrap-arround dialog.
415     */
416     void EndOfSearch (void);
417 
418     /** Show a dialog that tells the user that the search has ended either
419         because there are no more matches after finding at least one or that
420         no match has been found at all.
421     */
422     void ShowEndOfSearchDialog (void);
423 
424     /** Show a dialog that asks the user whether to wrap arround to the
425         beginning/end of the document and continue with the search/spell
426         check.
427     */
428     bool ShowWrapArroundDialog (void);
429 
430     /** Check whether the object pointed to by the iterator is a valid text
431         object.
432         @param aPosition
433             The object for which to test whether it is a valid text object.
434     */
435     bool IsValidTextObject (const ::sd::outliner::IteratorPosition& rPosition);
436 
437     /** Put text of current text object into outliner so that the text can
438         be searched/spell checked.
439     */
440     void PutTextIntoOutliner (void);
441 
442     /** Prepare to do spell checking on the current text object.  This
443         includes putting it into edit mode.  Under certain conditions this
444         method sets <member>mbEndOfSearch</member> to <TRUE/>.
445     */
446     void PrepareSpellCheck (void);
447 
448     /** Prepare to search and replace on the current text object.  This
449         includes putting it into edit mode.
450     */
451     void PrepareSearchAndReplace (void);
452 
453     /** Prepare to do a text conversion on the current text
454 		object. This includes putting it into edit mode.
455 	*/
456     void PrepareConversion (void);
457 
458     /** Switch to a new view mode.  Try to restore the original edit mode
459         before doing so.
460         @param ePageKind
461             Specifies the new view mode.
462     */
463     void SetViewMode (PageKind ePageKind);
464 
465     /** Switch to the page or master page specified by the
466         <member>mnPage</member> index.  Master page mode is specified by
467         <member>meEditMode</member>.
468         @param eEditMode
469             The new edit mode.
470         @param nPageIndex
471             The new page index.
472     */
473     void SetPage (EditMode eEditMode, sal_uInt16 nPageIndex);
474 
475     /** Switch on edit mode for the currently selected text object.
476     */
477     void EnterEditMode (sal_Bool bGrabFocus=sal_True);
478 
479     /** Return the position at which a new search is started with respect to
480         the search direction as specified by the argument.
481         @return
482             The position mentioned above in form of a selection with start
483             equals end.
484     */
485     ESelection GetSearchStartPosition (void);
486 
487     /** Detect whether there exists a previous match.  Note that only the
488         absence of such a match can be detected reliably.  An existing match
489         is assumed when the search started not at the beginning/end of the
490         presentation.  This does not have to be true.  The user can have set
491         the cursor at the middle of the text without a prior search.
492         @return
493             Returns </True> when there is no previous match and </False>
494             when there may be one.
495     */
496     bool HasNoPreviousMatch (void);
497 
498     /** Handle a failed search (with or without replace) for the outline
499         mode.  Show message boxes when the search failed completely,
500         i.e. there is no match in the whole presentation, or when no further
501         match exists.
502         @return
503             The returned value indicates whether another (wrapped arround)
504             search shall take place.  If that is so, then it is the caller's
505             responsibility to set the cursor position accordingly.
506     */
507     bool HandleFailedSearch (void);
508 
509     /** Take a position as returned by an object iterator and switch to the
510         view and page on which the object specified by this position is
511         located.
512         @param rPosition
513             This position points to a <type>SdrObject</type> object and
514             contains the view and page where it is located.
515         @return
516             Return a pointer to the <type>SdrObject</type>.
517     */
518     SdrObject* SetObject (const ::sd::outliner::IteratorPosition& rPosition);
519 
520     /** Use this method when the view shell in which to search has changed.
521         It handles i.e. registering at the associated view as selection
522         change listener.
523     */
524     void SetViewShell (const ::boost::shared_ptr<ViewShell>& rpViewShell);
525 
526     /** Activate or deactivate the search in the current selection.  Call
527         this method whenever the selection has changed.  This method creates
528         a copy of the current selection and reassings the object iterator to
529         the current() iterator.
530     */
531     void HandleChangedSelection (void);
532 
533     /** Initiate the spell check of the next relevant text object.
534         When the outline view is active then this method is called
535         after a wrap arround to continue at the beginning of the document.
536         @return
537             Returns <TRUE/> to indicate that another call to this method is
538             required.  When all text objects have been processed then
539             <FALSE/> is returned.
540     */
541     virtual sal_Bool SpellNextDocument (void);
542 
543     /** Show the given message box and make it modal.  It is assumed that
544         the parent of the given dialog is NULL, i.e. the application
545         window.  This function makes sure that the otherwise non-modal
546         search dialog, if visible, is locked, too.
547     */
548     sal_uInt16 ShowModalMessageBox (Dialog& rMessageBox);
549 };
550 
551 } // end of namespace sd
552 
553 #endif
554 
555