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