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 candidate 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 occurred 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 automatically 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 around 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 around) 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 around 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