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