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