update dev300-m58
[ooovba.git] / sd / source / ui / view / Outliner.cxx
blob8a67904c1937b31f43687994b22b7a6e20581385
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: Outliner.cxx,v $
10 * $Revision: 1.37.24.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sd.hxx"
34 #include "Outliner.hxx"
35 #include <vcl/wrkwin.hxx>
36 #include <sfx2/srchitem.hxx>
37 #include <svx/colritem.hxx>
38 #include <svx/eeitem.hxx>
39 #include <svx/editstat.hxx>
40 #include <vcl/outdev.hxx>
41 #ifndef _DLGUTIL_HXX
42 #include <svx/dlgutil.hxx>
43 #endif
44 #include <svx/xtable.hxx>
45 #include <vcl/msgbox.hxx>
46 #include <sfx2/dispatch.hxx>
47 #include <sfx2/printer.hxx>
48 #include <svx/svxerr.hxx>
49 #include <svx/svdotext.hxx>
50 #include <svx/unolingu.hxx>
51 #include <svx/svditer.hxx>
52 #include <comphelper/extract.hxx>
53 #include <com/sun/star/linguistic2/XSpellChecker1.hpp>
54 #include <com/sun/star/beans/XPropertySet.hpp>
55 #include <comphelper/processfactory.hxx>
56 #include <svx/eeitem.hxx>
57 #include <svx/forbiddencharacterstable.hxx>
58 #include <svx/srchdlg.hxx>
59 #include <svtools/linguprops.hxx>
60 #include <svtools/lingucfg.hxx>
61 #include <svx/editeng.hxx>
62 #include <vcl/metric.hxx>
63 #include <sfx2/viewfrm.hxx>
65 #include "strings.hrc"
66 #include "sdstring.hrc"
67 #include "eetext.hxx"
68 #include "sdpage.hxx"
69 #include "app.hxx"
70 #include "Window.hxx"
71 #include "sdresid.hxx"
72 #include "DrawViewShell.hxx"
73 #include "OutlineViewShell.hxx"
74 #include "drawdoc.hxx"
75 #include "DrawDocShell.hxx"
76 #include "FrameView.hxx"
77 #include "optsitem.hxx"
78 #include "drawview.hxx"
79 #include "ViewShellBase.hxx"
80 #include "SpellDialogChildWindow.hxx"
81 #include "ToolBarManager.hxx"
82 #include "framework/FrameworkHelper.hxx"
84 using ::rtl::OUString;
85 using namespace ::com::sun::star;
86 using namespace ::com::sun::star::uno;
87 using namespace ::com::sun::star::lang;
88 using namespace ::com::sun::star::linguistic2;
90 class SfxStyleSheetPool;
92 namespace sd {
94 class Outliner::Implementation
96 public:
97 /** The original edit mode directly after switching to a different view
98 mode. Used for restoring the edit mode when leaving that view mode
99 again.
101 EditMode meOriginalEditMode;
103 Implementation (void);
104 ~Implementation (void);
106 /** Return the OutlinerView that was provided by the last call to
107 ProvideOutlinerView() (or NULL when there was no such call.)
109 OutlinerView* GetOutlinerView (void);
111 /** Provide in the member mpOutlineView an instance of OutlinerView that
112 is either taken from the ViewShell, when it is an OutlineViewShell,
113 or is created. When an OutlinerView already exists it is initialied.
115 void ProvideOutlinerView (
116 Outliner& rOutliner,
117 const ::boost::shared_ptr<ViewShell>& rpViewShell,
118 ::Window* pWindow);
120 /** This method is called when the OutlinerView is no longer used.
122 void ReleaseOutlinerView (void);
124 private:
125 /** Flag that specifies whether we own the outline view pointed to by
126 <member>mpOutlineView</member> and thus have to
127 delete it in <member>EndSpelling()</member>.
129 bool mbOwnOutlineView;
131 /** The outline view used for searching and spelling. If searching or
132 spell checking an outline view this data member points to that view.
133 For all other views an instance is created. The
134 <member>mbOwnOutlineView</member> distinguishes between both cases.
136 OutlinerView* mpOutlineView;
142 /*************************************************************************
144 |* Ctor
146 \************************************************************************/
148 Outliner::Outliner( SdDrawDocument* pDoc, USHORT nMode )
149 : SdrOutliner( &pDoc->GetItemPool(), nMode ),
150 mpImpl(new Implementation()),
151 meMode(SEARCH),
152 mpView(NULL),
153 mpViewShell(),
154 mpWindow(NULL),
155 mpDrawDocument(pDoc),
156 mnConversionLanguage(LANGUAGE_NONE),
157 mnIgnoreCurrentPageChangesLevel(0),
158 mbStringFound(FALSE),
159 mbMatchMayExist(false),
160 mnPageCount(0),
161 mnObjectCount(0),
162 mbEndOfSearch(FALSE),
163 mbFoundObject(FALSE),
164 mbError(FALSE),
165 mbDirectionIsForward(true),
166 mbRestrictSearchToSelection(false),
167 maMarkListCopy(),
168 mbProcessCurrentViewOnly(false),
169 mpObj(NULL),
170 mpFirstObj(NULL),
171 mpTextObj(NULL),
172 mnText(0),
173 mpParaObj(NULL),
174 meStartViewMode(PK_STANDARD),
175 meStartEditMode(EM_PAGE),
176 mnStartPageIndex((USHORT)-1),
177 mpStartEditedObject(NULL),
178 maStartSelection(),
179 mpSearchItem(NULL),
180 maObjectIterator(),
181 maCurrentPosition(),
182 maSearchStartPosition(),
183 maLastValidPosition(),
184 mbSelectionHasChanged(false),
185 mbExpectingSelectionChangeEvent(false),
186 mbWholeDocumentProcessed(false),
187 mbPrepareSpellingPending(true),
188 mbViewShellValid(true)
190 SetStyleSheetPool((SfxStyleSheetPool*) mpDrawDocument->GetStyleSheetPool());
191 SetEditTextObjectPool( &pDoc->GetItemPool() );
192 SetCalcFieldValueHdl(LINK(SD_MOD(), SdModule, CalcFieldValueHdl));
193 SetForbiddenCharsTable( pDoc->GetForbiddenCharsTable() );
195 ULONG nCntrl = GetControlWord();
196 nCntrl |= EE_CNTRL_ALLOWBIGOBJS;
197 nCntrl |= EE_CNTRL_URLSFXEXECUTE;
198 nCntrl |= EE_CNTRL_MARKFIELDS;
199 nCntrl |= EE_CNTRL_AUTOCORRECT;
201 BOOL bOnlineSpell = false;
203 DrawDocShell* pDocSh = mpDrawDocument->GetDocSh();
205 if (pDocSh)
207 bOnlineSpell = mpDrawDocument->GetOnlineSpell();
209 else
211 bOnlineSpell = false;
215 const SvtLinguConfig aLinguConfig;
216 Any aAny;
218 aAny = aLinguConfig.GetProperty(
219 rtl::OUString::createFromAscii( UPN_IS_SPELL_AUTO ) );
220 aAny >>= bOnlineSpell;
222 catch( ... )
224 DBG_ERROR( "Ill. type in linguistic property" );
228 if (bOnlineSpell)
229 nCntrl |= EE_CNTRL_ONLINESPELLING;
230 else
231 nCntrl &= ~EE_CNTRL_ONLINESPELLING;
233 SetControlWord(nCntrl);
235 Reference< XSpellChecker1 > xSpellChecker( LinguMgr::GetSpellChecker() );
236 if ( xSpellChecker.is() )
237 SetSpeller( xSpellChecker );
239 Reference< XHyphenator > xHyphenator( LinguMgr::GetHyphenator() );
240 if( xHyphenator.is() )
241 SetHyphenator( xHyphenator );
243 SetDefaultLanguage( Application::GetSettings().GetLanguage() );
249 /// Nothing spectecular in the destructor.
250 Outliner::~Outliner (void)
252 mpImpl.reset();
258 /** Prepare find&replace or spellchecking. This distinguishes between three
259 cases:
260 <ol>
261 <li>The current shell is a <type>DrawViewShell</type>: Create a
262 <type>OutlinerView</type> object and search all objects of (i) the
263 current mark list, (ii) of the current view, or (iii) of all the view
264 combinations:
265 <ol>
266 <li>Draw view, slide view</li>
267 <li>Draw view, background view</li>
268 <li>Notes view, slide view</li>
269 <li>Notes view, background view</li>
270 <li>Handout view, slide view</li>
271 <li>Handout view, background view</li>
272 </ol>
274 <li>When the current shell is a <type>SdOutlineViewShell</type> then
275 directly operate on it. No switching into other views takes place.</li>
277 <li>For a <type>SlideViewShell</type> no action is performed.</li>
278 </ol>
280 void Outliner::PrepareSpelling (void)
282 if (mbViewShellValid)
284 mbPrepareSpellingPending = false;
286 ViewShellBase* pBase = PTR_CAST(ViewShellBase,SfxViewShell::Current());
287 if (pBase != NULL)
288 SetViewShell (pBase->GetMainViewShell());
289 SetRefDevice( SD_MOD()->GetRefDevice( *mpDrawDocument->GetDocSh() ) );
291 if (mpViewShell.get() != NULL)
293 mbStringFound = FALSE;
295 mbWholeDocumentProcessed = false;
296 // Supposed that we are not located at the very beginning/end of
297 // the document then there may be a match in the document
298 // prior/after the current position.
299 mbMatchMayExist = TRUE;
301 maObjectIterator = ::sd::outliner::Iterator();
302 maSearchStartPosition = ::sd::outliner::Iterator();
303 RememberStartPosition();
305 mpImpl->ProvideOutlinerView(*this, mpViewShell, mpWindow);
307 HandleChangedSelection ();
309 ClearModifyFlag();
317 void Outliner::StartSpelling (void)
319 meMode = SPELL;
320 mbDirectionIsForward = true;
321 mpSearchItem = NULL;
324 /** Proxy for method from base class to avoid compiler warning */
325 void Outliner::StartSpelling(EditView& rView, unsigned char c)
327 SdrOutliner::StartSpelling( rView, c );
330 /** Free all resources acquired during the search/spell check. After a
331 spell check the start position is restored here.
333 void Outliner::EndSpelling (void)
335 if (mbViewShellValid)
337 ViewShellBase* pBase = PTR_CAST(ViewShellBase,SfxViewShell::Current());
338 if (pBase != NULL)
339 mpViewShell = pBase->GetMainViewShell();
340 else
341 mpViewShell.reset();
343 // When in <member>PrepareSpelling()</member> a new outline view has
344 // been created then delete it here.
345 sal_Bool bViewIsDrawViewShell(mpViewShell.get()!=NULL
346 && mpViewShell->ISA(DrawViewShell));
347 if (bViewIsDrawViewShell)
349 SetStatusEventHdl(Link());
350 mpView = mpViewShell->GetView();
351 mpView->UnmarkAllObj (mpView->GetSdrPageView());
352 mpView->SdrEndTextEdit();
353 // Make FuSelection the current function.
354 mpViewShell->GetDispatcher()->Execute(
355 SID_OBJECT_SELECT,
356 SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD);
358 // Remove and, if previously created by us, delete the outline
359 // view.
360 OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
361 if (pOutlinerView != NULL)
363 RemoveView(pOutlinerView);
364 mpImpl->ReleaseOutlinerView();
367 SetUpdateMode(TRUE);
370 // #95811# Before clearing the modify flag use it as a hint that
371 // changes were done at SpellCheck
372 if(IsModified())
374 if(mpView && mpView->ISA(OutlineView))
375 static_cast<OutlineView*>(mpView)->PrepareClose(FALSE);
376 if(mpDrawDocument && !mpDrawDocument->IsChanged())
377 mpDrawDocument->SetChanged(TRUE);
380 // #95811# now clear the modify flag to have a specified state of
381 // Outliner
382 ClearModifyFlag();
384 // When spell checking then restore the start position.
385 if (meMode==SPELL || meMode==TEXT_CONVERSION)
386 RestoreStartPosition ();
389 mpViewShell.reset();
390 mpView = NULL;
391 mpWindow = NULL;
397 BOOL Outliner::SpellNextDocument (void)
399 if (mpViewShell->ISA(OutlineViewShell))
401 // When doing a spell check in the outline view then there is
402 // only one document.
403 mbEndOfSearch = true;
404 EndOfSearch ();
406 else
408 if (mpView->ISA(OutlineView))
409 ((OutlineView*)mpView)->PrepareClose(FALSE);
410 mpDrawDocument->GetDocSh()->SetWaitCursor( TRUE );
412 Initialize (true);
414 mpWindow = mpViewShell->GetActiveWindow();
415 OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
416 if (pOutlinerView != NULL)
417 pOutlinerView->SetWindow(mpWindow);
418 ProvideNextTextObject ();
420 mpDrawDocument->GetDocSh()->SetWaitCursor( FALSE );
421 ClearModifyFlag();
424 return mbEndOfSearch ? FALSE : TRUE;
428 void Outliner::HandleOutsideChange (ChangeHint eHint)
430 switch (eHint)
432 case CH_VIEW_SHELL_INVALID:
433 EndSpelling();
434 mbPrepareSpellingPending = true;
435 mbViewShellValid = false;
436 break;
438 case CH_VIEW_SHELL_VALID:
439 mbViewShellValid = true;
440 break;
446 /*************************************************************************
448 |* Spelling: naechstes TextObjekt pruefen
450 \************************************************************************/
452 ::svx::SpellPortions Outliner::GetNextSpellSentence (void)
454 ::svx::SpellPortions aResult;
456 DetectChange();
457 // Iterate over sentences and text shapes until a sentence with a
458 // spelling error has been found. If no such sentence can be
459 // found the loop is left through a break.
460 // It is the responsibility of the sd outliner object to correctly
461 // iterate over all text shapes, i.e. switch between views, wrap
462 // arround at the end of the document, stop when all text shapes
463 // have been examined exactly once.
464 bool bFoundNextSentence = false;
465 while ( ! bFoundNextSentence)
467 OutlinerView* pOutlinerView = GetView(0);
468 if (pOutlinerView != NULL)
470 ESelection aCurrentSelection (pOutlinerView->GetSelection());
471 if ( ! mbMatchMayExist
472 && maStartSelection.IsLess(aCurrentSelection))
473 EndOfSearch();
475 // Advance to the next sentence.
476 bFoundNextSentence = SpellSentence (
477 pOutlinerView->GetEditView(),
478 aResult, false);
481 // When no sentence with spelling errors has been found in the
482 // currently selected text shape or there is no selected text
483 // shape then advance to the next text shape.
484 if ( ! bFoundNextSentence)
485 if ( ! SpellNextDocument())
486 // All text objects have been processed so exit the
487 // loop and return an empty portions list.
488 break;
491 return aResult;
497 /** Go to next match.
499 bool Outliner::StartSearchAndReplace (const SvxSearchItem* pSearchItem)
501 BOOL bEndOfSearch = TRUE;
503 if (mbViewShellValid)
505 mpDrawDocument->GetDocSh()->SetWaitCursor( TRUE );
506 if (mbPrepareSpellingPending)
507 PrepareSpelling();
508 ViewShellBase* pBase = PTR_CAST(ViewShellBase,SfxViewShell::Current());
509 // Determine whether we have to abort the search. This is necessary
510 // when the main view shell does not support searching.
511 bool bAbort = false;
512 if (pBase != NULL)
514 ::boost::shared_ptr<ViewShell> pShell (pBase->GetMainViewShell());
515 SetViewShell(pShell);
516 if (pShell.get() == NULL)
517 bAbort = true;
518 else
519 switch (pShell->GetShellType())
521 case ViewShell::ST_DRAW:
522 case ViewShell::ST_IMPRESS:
523 case ViewShell::ST_NOTES:
524 case ViewShell::ST_HANDOUT:
525 case ViewShell::ST_OUTLINE:
526 bAbort = false;
527 break;
528 default:
529 bAbort = true;
530 break;
534 if ( ! bAbort)
536 meMode = SEARCH;
537 mpSearchItem = pSearchItem;
539 mbFoundObject = FALSE;
541 Initialize ( ! mpSearchItem->GetBackward());
543 USHORT nCommand = mpSearchItem->GetCommand();
544 if (nCommand == SVX_SEARCHCMD_REPLACE_ALL)
545 bEndOfSearch = SearchAndReplaceAll ();
546 else
548 RememberStartPosition ();
549 bEndOfSearch = SearchAndReplaceOnce ();
550 //#107233# restore start position if nothing was found
551 if(!mbStringFound)
552 RestoreStartPosition ();
553 else
554 mnStartPageIndex = (USHORT)-1;
557 else
558 mpDrawDocument->GetDocSh()->SetWaitCursor( FALSE );
561 return bEndOfSearch;
567 void Outliner::Initialize (bool bDirectionIsForward)
569 bool bOldDirectionIsForward = mbDirectionIsForward;
570 mbDirectionIsForward = bDirectionIsForward;
572 if (maObjectIterator == ::sd::outliner::Iterator())
574 // Initialize a new search.
575 maObjectIterator = ::sd::outliner::OutlinerContainer(this).current();
576 maCurrentPosition = *maObjectIterator;
578 // In case we are searching in an outline view then first remove the
579 // current selection and place cursor at its start or end.
580 if (mpViewShell->ISA(OutlineViewShell))
582 ESelection aSelection = mpImpl->GetOutlinerView()->GetSelection ();
583 if (mbDirectionIsForward)
585 aSelection.nEndPara = aSelection.nStartPara;
586 aSelection.nEndPos = aSelection.nStartPos;
588 else
590 aSelection.nStartPara = aSelection.nEndPara;
591 aSelection.nStartPos = aSelection.nEndPos;
593 mpImpl->GetOutlinerView()->SetSelection (aSelection);
596 // When not beginning the search at the beginning of the search area
597 // then there may be matches before the current position.
598 mbMatchMayExist = (maObjectIterator!=::sd::outliner::OutlinerContainer(this).begin());
600 else if (bOldDirectionIsForward != mbDirectionIsForward)
602 // Requested iteration direction has changed. Turn arround the iterator.
603 maObjectIterator.Reverse();
604 // The iterator has pointed to the object one ahead/before the current
605 // one. Now move it to the one before/ahead the current one.
606 ++maObjectIterator;
607 ++maObjectIterator;
609 mbMatchMayExist = true;
612 // Initialize the last valid position with where the search starts so
613 // that it always points to a valid position.
614 maLastValidPosition = *::sd::outliner::OutlinerContainer(this).current();
620 bool Outliner::SearchAndReplaceAll (void)
622 // Save the current position to be restored after having replaced all
623 // matches.
624 RememberStartPosition ();
626 if (mpViewShell->ISA(OutlineViewShell))
628 // Put the cursor to the beginning/end of the outliner.
629 mpImpl->GetOutlinerView()->SetSelection (GetSearchStartPosition ());
631 // The outliner does all the work for us when we are in this mode.
632 SearchAndReplaceOnce();
634 else if (mpViewShell->ISA(DrawViewShell))
636 // Go to beginning/end of document.
637 maObjectIterator = ::sd::outliner::OutlinerContainer(this).begin();
638 // Switch to the current object only if it is a valid text object.
639 ::sd::outliner::IteratorPosition aNewPosition (*maObjectIterator);
640 if (IsValidTextObject (aNewPosition))
642 maCurrentPosition = aNewPosition;
643 SetObject (maCurrentPosition);
646 // Search/replace until the end of the document is reached.
647 bool bFoundMatch;
650 bFoundMatch = ! SearchAndReplaceOnce();
652 while (bFoundMatch);
655 RestoreStartPosition ();
657 return true;
663 bool Outliner::SearchAndReplaceOnce (void)
665 DetectChange ();
667 OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
668 DBG_ASSERT(pOutlinerView!=NULL && GetEditEngine().HasView( &pOutlinerView->GetEditView() ),
669 "SearchAndReplace without valid view!" );
671 if( NULL == pOutlinerView || !GetEditEngine().HasView( &pOutlinerView->GetEditView() ) )
672 return true;
674 if (mpViewShell != NULL)
676 mpView = mpViewShell->GetView();
677 mpWindow = mpViewShell->GetActiveWindow();
678 pOutlinerView->SetWindow(mpWindow);
680 if (mpViewShell->ISA(DrawViewShell) )
682 // When replacing we first check if there is a selection
683 // indicating a match. If there is then replace it. The
684 // following call to StartSearchAndReplace will then search for
685 // the next match.
686 if (meMode == SEARCH
687 && mpSearchItem->GetCommand() == SVX_SEARCHCMD_REPLACE)
688 if (pOutlinerView->GetSelection().HasRange())
689 pOutlinerView->StartSearchAndReplace(*mpSearchItem);
691 // Search for the next match.
692 ULONG nMatchCount = 0;
693 if (mpSearchItem->GetCommand() != SVX_SEARCHCMD_REPLACE_ALL)
694 nMatchCount = pOutlinerView->StartSearchAndReplace(*mpSearchItem);
696 // Go to the next text object when there have been no matches in
697 // the current object or the whole object has already been
698 // processed.
699 if (nMatchCount==0 || mpSearchItem->GetCommand()==SVX_SEARCHCMD_REPLACE_ALL)
701 ProvideNextTextObject ();
703 if ( ! mbEndOfSearch)
705 // Remember the current position as the last one with a
706 // text object.
707 maLastValidPosition = maCurrentPosition;
709 // Now that the mbEndOfSearch flag guards this block the
710 // following assertion and return should not be
711 // necessary anymore.
712 DBG_ASSERT(GetEditEngine().HasView(&pOutlinerView->GetEditView() ),
713 "SearchAndReplace without valid view!" );
714 if ( ! GetEditEngine().HasView( &pOutlinerView->GetEditView() ) )
716 mpDrawDocument->GetDocSh()->SetWaitCursor( FALSE );
717 return true;
720 if (meMode == SEARCH)
721 nMatchCount = pOutlinerView->StartSearchAndReplace(*mpSearchItem);
725 else if (mpViewShell->ISA(OutlineViewShell))
727 mpDrawDocument->GetDocSh()->SetWaitCursor (FALSE);
728 // The following loop is executed more then once only when a
729 // wrap arround search is done.
730 while (true)
732 int nResult = pOutlinerView->StartSearchAndReplace(*mpSearchItem);
733 if (nResult == 0)
735 if (HandleFailedSearch ())
737 pOutlinerView->SetSelection (GetSearchStartPosition ());
738 continue;
741 else
742 mbStringFound = true;
743 break;
748 mpDrawDocument->GetDocSh()->SetWaitCursor( FALSE );
750 return mbEndOfSearch;
756 /** Try to detect whether the document or the view (shell) has changed since
757 the last time <member>StartSearchAndReplace()</member> has been called.
759 void Outliner::DetectChange (void)
761 ::sd::outliner::IteratorPosition aPosition (maCurrentPosition);
763 ::boost::shared_ptr<DrawViewShell> pDrawViewShell (
764 ::boost::dynamic_pointer_cast<DrawViewShell>(mpViewShell));
766 // Detect whether the view has been switched from the outside.
767 if (pDrawViewShell.get() != NULL
768 && (aPosition.meEditMode != pDrawViewShell->GetEditMode()
769 || aPosition.mePageKind != pDrawViewShell->GetPageKind()))
771 // Either the edit mode or the page kind has changed.
772 SetStatusEventHdl(Link());
774 SdrPageView* pPageView = mpView->GetSdrPageView();
775 if (pPageView != NULL)
776 mpView->UnmarkAllObj (pPageView);
777 mpView->SdrEndTextEdit();
778 SetUpdateMode(FALSE);
779 OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
780 if (pOutlinerView != NULL)
781 pOutlinerView->SetOutputArea( Rectangle( Point(), Size(1, 1) ) );
782 if (meMode == SPELL)
783 SetPaperSize( Size(1, 1) );
784 SetText( String(), GetParagraph( 0 ) );
786 RememberStartPosition ();
788 mnPageCount = mpDrawDocument->GetSdPageCount(pDrawViewShell->GetPageKind());
789 maObjectIterator = ::sd::outliner::OutlinerContainer(this).current();
792 // Detect change of the set of selected objects. If their number has
793 // changed start again with the first selected object.
794 else if (DetectSelectionChange())
796 HandleChangedSelection ();
797 maObjectIterator = ::sd::outliner::OutlinerContainer(this).current();
800 // Detect change of page count. Restart search at first/last page in
801 // that case.
802 else if (aPosition.meEditMode == EM_PAGE
803 && mpDrawDocument->GetSdPageCount(aPosition.mePageKind) != mnPageCount)
805 // The number of pages has changed.
806 mnPageCount = mpDrawDocument->GetSdPageCount(aPosition.mePageKind);
807 maObjectIterator = ::sd::outliner::OutlinerContainer(this).current();
809 else if (aPosition.meEditMode == EM_MASTERPAGE
810 && mpDrawDocument->GetSdPageCount(aPosition.mePageKind) != mnPageCount)
812 // The number of master pages has changed.
813 mnPageCount = mpDrawDocument->GetSdPageCount(aPosition.mePageKind);
814 maObjectIterator = ::sd::outliner::OutlinerContainer(this).current();
821 bool Outliner::DetectSelectionChange (void)
823 bool bSelectionHasChanged = false;
824 ULONG nMarkCount = mpView->GetMarkedObjectList().GetMarkCount();
826 // If mpObj is NULL then we have not yet found our first match.
827 // Detecting a change makes no sense.
828 if (mpObj != NULL)
829 switch (nMarkCount)
831 case 0:
832 // The selection has changed when previously there have been
833 // selected objects.
834 bSelectionHasChanged = mbRestrictSearchToSelection;
835 break;
836 case 1:
837 // Check if the only selected object is not the one that we
838 // had selected.
839 if (mpView != NULL)
841 SdrMark* pMark = mpView->GetMarkedObjectList().GetMark(0);
842 if (pMark != NULL)
843 bSelectionHasChanged = (mpObj != pMark->GetMarkedSdrObj ());
845 break;
846 default:
847 // We had selected exactly one object.
848 bSelectionHasChanged = true;
849 break;
852 return bSelectionHasChanged;
858 void Outliner::RememberStartPosition (void)
860 if (mpViewShell->ISA(DrawViewShell))
862 ::boost::shared_ptr<DrawViewShell> pDrawViewShell (
863 ::boost::dynamic_pointer_cast<DrawViewShell>(mpViewShell));
864 if (pDrawViewShell.get() != NULL)
866 meStartViewMode = pDrawViewShell->GetPageKind();
867 meStartEditMode = pDrawViewShell->GetEditMode();
868 mnStartPageIndex = pDrawViewShell->GetCurPageId() - 1;
871 if (mpView != NULL)
873 mpStartEditedObject = mpView->GetTextEditObject();
874 if (mpStartEditedObject != NULL)
876 // Try to retrieve current caret position only when there is an
877 // edited object.
878 ::Outliner* pOutliner =
879 static_cast<DrawView*>(mpView)->GetTextEditOutliner();
880 if (pOutliner!=NULL && pOutliner->GetViewCount()>0)
882 OutlinerView* pOutlinerView = pOutliner->GetView(0);
883 maStartSelection = pOutlinerView->GetSelection();
888 else if (mpViewShell->ISA(OutlineViewShell))
890 // Remember the current cursor position.
891 OutlinerView* pView = GetView(0);
892 if (pView != NULL)
893 pView->GetSelection();
895 else
897 mnStartPageIndex = (USHORT)-1;
904 void Outliner::RestoreStartPosition (void)
906 bool bRestore = true;
907 // Take a negative start page index as inidicator that restoring the
908 // start position is not requested.
909 if (mnStartPageIndex == (USHORT)-1 )
910 bRestore = false;
911 // Dont't resore when the view shell is not valid.
912 if (mpViewShell == NULL)
913 bRestore = false;
914 if ( ! mbViewShellValid)
915 bRestore = false;
917 if (bRestore)
919 if (mpViewShell->ISA(DrawViewShell))
921 ::boost::shared_ptr<DrawViewShell> pDrawViewShell (
922 ::boost::dynamic_pointer_cast<DrawViewShell>(mpViewShell));
923 SetViewMode (meStartViewMode);
924 if (pDrawViewShell.get() != NULL)
925 SetPage (meStartEditMode, mnStartPageIndex);
928 if (mpStartEditedObject != NULL)
930 // Turn on the text toolbar as it is done in FuText so that
931 // undo manager setting/restoring in
932 // sd::View::{Beg,End}TextEdit() works on the same view shell.
933 mpViewShell->GetViewShellBase().GetToolBarManager()->SetToolBarShell(
934 ToolBarManager::TBG_FUNCTION,
935 RID_DRAW_TEXT_TOOLBOX);
937 mpView->SdrBeginTextEdit(mpStartEditedObject);
938 ::Outliner* pOutliner =
939 static_cast<DrawView*>(mpView)->GetTextEditOutliner();
940 if (pOutliner!=NULL && pOutliner->GetViewCount()>0)
942 OutlinerView* pOutlinerView = pOutliner->GetView(0);
943 pOutlinerView->SetSelection(maStartSelection);
947 else if (mpViewShell->ISA(OutlineViewShell))
949 // Set cursor to its old position.
950 GetView(0)->SetSelection (maStartSelection);
958 /** The main purpose of this method is to iterate over all shape objects of
959 the search area (current selection, current view, or whole document)
960 until a text object has been found that contains at least one match or
961 until no such object can be found anymore. These two conditions are
962 expressed by setting one of the flags <member>mbFoundObject</member> or
963 <member>mbEndOfSearch</member> to <TRUE/>.
965 void Outliner::ProvideNextTextObject (void)
967 mbEndOfSearch = false;
968 mbFoundObject = false;
970 mpView->UnmarkAllObj (mpView->GetSdrPageView());
973 mpView->SdrEndTextEdit();
975 catch (::com::sun::star::uno::Exception e)
977 OSL_TRACE ("Outliner %p: caught exception while ending text edit mode", this);
979 SetUpdateMode(FALSE);
980 OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
981 if (pOutlinerView != NULL)
982 pOutlinerView->SetOutputArea( Rectangle( Point(), Size(1, 1) ) );
983 if (meMode == SPELL)
984 SetPaperSize( Size(1, 1) );
985 SetText( String(), GetParagraph( 0 ) );
987 mpTextObj = NULL;
989 // Iterate until a valid text object has been found or the search ends.
992 mpObj = NULL;
993 mpParaObj = NULL;
995 if (maObjectIterator != ::sd::outliner::OutlinerContainer(this).end())
997 maCurrentPosition = *maObjectIterator;
998 // Switch to the current object only if it is a valid text object.
999 if (IsValidTextObject (maCurrentPosition))
1001 mpObj = SetObject (maCurrentPosition);
1003 ++maObjectIterator;
1005 if (mpObj != NULL)
1007 PutTextIntoOutliner ();
1009 if (mpViewShell != NULL)
1010 switch (meMode)
1012 case SEARCH:
1013 PrepareSearchAndReplace ();
1014 break;
1015 case SPELL:
1016 PrepareSpellCheck ();
1017 break;
1018 case TEXT_CONVERSION:
1019 PrepareConversion();
1020 break;
1024 else
1026 mbEndOfSearch = true;
1027 EndOfSearch ();
1030 while ( ! (mbFoundObject || mbEndOfSearch));
1036 void Outliner::EndOfSearch (void)
1038 // Before we display a dialog we first jump to where the last valid text
1039 // object was found. All page and view mode switching since then was
1040 // temporary and should not be visible to the user.
1041 if ( ! mpViewShell->ISA(OutlineViewShell))
1042 SetObject (maLastValidPosition);
1044 if (mbRestrictSearchToSelection)
1045 ShowEndOfSearchDialog ();
1046 else
1048 // When no match has been found so far then terminate the search.
1049 if ( ! mbMatchMayExist)
1051 ShowEndOfSearchDialog ();
1052 mbEndOfSearch = TRUE;
1054 // Ask the user whether to wrap arround and continue the search or
1055 // to terminate.
1056 else if (meMode==TEXT_CONVERSION || ShowWrapArroundDialog ())
1058 mbMatchMayExist = false;
1059 // Everything back to beginning (or end?) of the document.
1060 maObjectIterator = ::sd::outliner::OutlinerContainer(this).begin();
1061 if (mpViewShell->ISA(OutlineViewShell))
1063 // Set cursor to first character of the document.
1064 OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
1065 if (pOutlinerView != NULL)
1066 pOutlinerView->SetSelection (GetSearchStartPosition ());
1069 mbEndOfSearch = false;
1071 else
1073 // No wrap arround.
1074 mbEndOfSearch = true;
1082 void Outliner::InitPage (USHORT nPageIndex)
1084 (void)nPageIndex;
1086 ::sd::outliner::IteratorPosition aPosition (*maObjectIterator);
1087 if (aPosition.meEditMode == EM_PAGE)
1088 mnPageCount = mpDrawDocument->GetSdPageCount(aPosition.mePageKind);
1089 else
1090 mnPageCount = mpDrawDocument->GetMasterSdPageCount(aPosition.mePageKind);
1096 void Outliner::ShowEndOfSearchDialog (void)
1098 String aString;
1099 if (meMode == SEARCH)
1101 if (mbStringFound)
1102 aString = String( SdResId(STR_END_SEARCHING) );
1103 else
1104 aString = String( SdResId(STR_STRING_NOTFOUND) );
1106 else
1108 if (mpView->AreObjectsMarked())
1109 aString = String(SdResId(STR_END_SPELLING_OBJ));
1110 else
1111 aString = String(SdResId(STR_END_SPELLING));
1114 // Show the message in an info box that is modal with respect to the
1115 // whole application.
1116 InfoBox aInfoBox (NULL, aString);
1117 ShowModalMessageBox (aInfoBox);
1119 mbWholeDocumentProcessed = true;
1125 bool Outliner::ShowWrapArroundDialog (void)
1127 bool bDoWrapArround = false;
1129 // Determine whether to show the dialog.
1130 bool bShowDialog = false;
1131 if (mpSearchItem != NULL)
1133 // When searching display the dialog only for single find&replace.
1134 USHORT nCommand = mpSearchItem->GetCommand();
1135 bShowDialog = (nCommand==SVX_SEARCHCMD_REPLACE)
1136 || (nCommand==SVX_SEARCHCMD_FIND);
1138 else
1139 // Spell checking needs the dialog, too.
1140 bShowDialog = (meMode == SPELL);
1142 if (bShowDialog)
1144 // The question text depends on the search direction.
1145 BOOL bImpress = mpDrawDocument!=NULL
1146 && mpDrawDocument->GetDocumentType() == DOCUMENT_TYPE_IMPRESS;
1147 USHORT nStringId;
1148 if (mbDirectionIsForward)
1149 nStringId = bImpress
1150 ? STR_SAR_WRAP_FORWARD
1151 : STR_SAR_WRAP_FORWARD_DRAW;
1152 else
1153 nStringId = bImpress
1154 ? STR_SAR_WRAP_BACKWARD
1155 : STR_SAR_WRAP_BACKWARD_DRAW;
1157 // Pop up question box that asks the user whether to wrap arround.
1158 // The dialog is made modal with respect to the whole application.
1159 QueryBox aQuestionBox (
1160 NULL,
1161 WB_YES_NO | WB_DEF_YES,
1162 String(SdResId(nStringId)));
1163 aQuestionBox.SetImage (QueryBox::GetStandardImage());
1164 USHORT nBoxResult = ShowModalMessageBox(aQuestionBox);
1165 bDoWrapArround = (nBoxResult == BUTTONID_YES);
1168 return bDoWrapArround;
1174 bool Outliner::IsValidTextObject (const ::sd::outliner::IteratorPosition& rPosition)
1176 SdrTextObj* pObject = dynamic_cast< SdrTextObj* >( rPosition.mxObject.get() );
1177 return (pObject != NULL) && pObject->HasText() && ! pObject->IsEmptyPresObj();
1183 void Outliner::PutTextIntoOutliner()
1185 mpTextObj = dynamic_cast<SdrTextObj*>( mpObj );
1186 if ( mpTextObj && mpTextObj->HasText() && !mpTextObj->IsEmptyPresObj() )
1188 SdrText* pText = mpTextObj->getText( mnText );
1189 mpParaObj = pText ? pText->GetOutlinerParaObject() : NULL;
1191 if (mpParaObj != NULL)
1193 SetText(*mpParaObj);
1195 ClearModifyFlag();
1198 else
1200 mpTextObj = NULL;
1207 void Outliner::PrepareSpellCheck (void)
1209 EESpellState eState = HasSpellErrors();
1210 DBG_ASSERT(eState != EE_SPELL_NOSPELLER, "No SpellChecker");
1212 if (eState == EE_SPELL_NOLANGUAGE)
1214 mbError = TRUE;
1215 mbEndOfSearch = TRUE;
1216 ErrorBox aErrorBox (NULL,
1217 WB_OK,
1218 String(SdResId(STR_NOLANGUAGE)));
1219 ShowModalMessageBox (aErrorBox);
1221 else if (eState != EE_SPELL_OK)
1223 // When spell checking we have to test whether we have processed the
1224 // whole document and have reached the start page again.
1225 if (meMode == SPELL)
1227 if (maSearchStartPosition == ::sd::outliner::Iterator())
1228 // Remember the position of the first text object so that we
1229 // know when we have processed the whole document.
1230 maSearchStartPosition = maObjectIterator;
1231 else if (maSearchStartPosition == maObjectIterator)
1233 mbEndOfSearch = true;
1237 EnterEditMode( FALSE );
1244 void Outliner::PrepareSearchAndReplace (void)
1246 if (HasText( *mpSearchItem ))
1248 mbStringFound = true;
1249 mbMatchMayExist = true;
1251 EnterEditMode ();
1253 mpDrawDocument->GetDocSh()->SetWaitCursor( FALSE );
1254 // Start seach at the right end of the current object's text
1255 // depending on the search direction.
1256 OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
1257 if (pOutlinerView != NULL)
1258 pOutlinerView->SetSelection (GetSearchStartPosition ());
1265 void Outliner::SetViewMode (PageKind ePageKind)
1267 ::boost::shared_ptr<DrawViewShell> pDrawViewShell(
1268 ::boost::dynamic_pointer_cast<DrawViewShell>(mpViewShell));
1269 if (pDrawViewShell.get()!=NULL && ePageKind != pDrawViewShell->GetPageKind())
1271 // Restore old edit mode.
1272 pDrawViewShell->ChangeEditMode(mpImpl->meOriginalEditMode, FALSE);
1274 SetStatusEventHdl(Link());
1275 ::rtl::OUString sViewURL;
1276 switch (ePageKind)
1278 case PK_STANDARD:
1279 default:
1280 sViewURL = framework::FrameworkHelper::msImpressViewURL;
1281 break;
1282 case PK_NOTES:
1283 sViewURL = framework::FrameworkHelper::msNotesViewURL;
1284 break;
1285 case PK_HANDOUT:
1286 sViewURL = framework::FrameworkHelper::msHandoutViewURL;
1287 break;
1289 // The text object iterator is destroyed when the shells are
1290 // switched but we need it so save it and restore it afterwards.
1291 ::sd::outliner::Iterator aIterator (maObjectIterator);
1292 bool bMatchMayExist = mbMatchMayExist;
1294 ViewShellBase& rBase = mpViewShell->GetViewShellBase();
1295 SetViewShell(::boost::shared_ptr<ViewShell>());
1296 framework::FrameworkHelper::Instance(rBase)->RequestView(
1297 sViewURL,
1298 framework::FrameworkHelper::msCenterPaneURL);
1300 // Force (well, request) a synchronous update of the configuration.
1301 // In a better world we would handle the asynchronous view update
1302 // instead. But that would involve major restucturing of the
1303 // Outliner code.
1304 framework::FrameworkHelper::Instance(rBase)->RequestSynchronousUpdate();
1305 SetViewShell(rBase.GetMainViewShell());
1307 // Switching to another view shell has intermediatly called
1308 // EndSpelling(). A PrepareSpelling() is pending, so call that now.
1309 PrepareSpelling();
1311 // Update the number of pages so that
1312 // <member>DetectChange()</member> has the correct value to compare
1313 // to.
1314 mnPageCount = mpDrawDocument->GetSdPageCount(ePageKind);
1316 maObjectIterator = aIterator;
1317 mbMatchMayExist = bMatchMayExist;
1319 // Save edit mode so that it can be restored when switching the view
1320 // shell again.
1321 pDrawViewShell = ::boost::dynamic_pointer_cast<DrawViewShell>(mpViewShell);
1322 OSL_ASSERT(pDrawViewShell.get()!=NULL);
1323 if (pDrawViewShell.get() != NULL)
1324 mpImpl->meOriginalEditMode = pDrawViewShell->GetEditMode();
1331 void Outliner::SetPage (EditMode eEditMode, USHORT nPageIndex)
1333 if ( ! mbRestrictSearchToSelection)
1335 ::boost::shared_ptr<DrawViewShell> pDrawViewShell(
1336 ::boost::dynamic_pointer_cast<DrawViewShell>(mpViewShell));
1337 OSL_ASSERT(pDrawViewShell.get()!=NULL);
1338 if (pDrawViewShell.get() != NULL)
1340 pDrawViewShell->ChangeEditMode(eEditMode, FALSE);
1341 pDrawViewShell->SwitchPage(nPageIndex);
1349 void Outliner::EnterEditMode (BOOL bGrabFocus)
1351 OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
1352 if (mbViewShellValid && pOutlinerView != NULL)
1354 pOutlinerView->SetOutputArea( Rectangle( Point(), Size(1, 1)));
1355 SetPaperSize( mpTextObj->GetLogicRect().GetSize() );
1356 SdrPageView* pPV = mpView->GetSdrPageView();
1358 // Make FuText the current function.
1359 SfxUInt16Item aItem (SID_TEXTEDIT, 1);
1360 mpViewShell->GetDispatcher()->
1361 Execute(SID_TEXTEDIT, SFX_CALLMODE_SYNCHRON |
1362 SFX_CALLMODE_RECORD, &aItem, 0L);
1364 // To be consistent with the usual behaviour in the Office the text
1365 // object that is put into edit mode would have also to be selected.
1366 // Starting the text edit mode is not enough so we do it here by
1367 // hand.
1368 mbExpectingSelectionChangeEvent = true;
1369 mpView->UnmarkAllObj (pPV);
1370 mpView->MarkObj (mpTextObj, pPV);
1372 if( mpTextObj )
1373 mpTextObj->setActiveText( mnText );
1375 // Turn on the edit mode for the text object.
1376 mpView->SdrBeginTextEdit(mpTextObj, pPV, mpWindow, sal_True, this, pOutlinerView, sal_True, sal_True, bGrabFocus);
1378 SetUpdateMode(TRUE);
1379 mbFoundObject = TRUE;
1386 /*************************************************************************
1388 |* SpellChecker: Error-LinkHdl
1390 \************************************************************************/
1392 IMPL_LINK_INLINE_START( Outliner, SpellError, void *, nLang )
1394 mbError = true;
1395 String aError( ::GetLanguageString( (LanguageType)(ULONG)nLang ) );
1396 ErrorHandler::HandleError(* new StringErrorInfo(
1397 ERRCODE_SVX_LINGU_LANGUAGENOTEXISTS, aError) );
1398 return 0;
1400 IMPL_LINK_INLINE_END( Outliner, SpellError, void *, nLang )
1405 ESelection Outliner::GetSearchStartPosition (void)
1407 ESelection aPosition;
1408 if (mbDirectionIsForward)
1410 // The default constructor uses the beginning of the text as default.
1411 aPosition = ESelection ();
1413 else
1415 // Retrieve the position after the last character in the last
1416 // paragraph.
1417 USHORT nParagraphCount = static_cast<USHORT>(GetParagraphCount());
1418 if (nParagraphCount == 0)
1419 aPosition = ESelection();
1420 else
1422 xub_StrLen nLastParagraphLength = GetEditEngine().GetTextLen (
1423 nParagraphCount-1);
1424 aPosition = ESelection (nParagraphCount-1, nLastParagraphLength);
1428 return aPosition;
1434 bool Outliner::HasNoPreviousMatch (void)
1436 OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
1438 DBG_ASSERT (pOutlinerView!=NULL, "outline view in Outliner::HasNoPreviousMatch is NULL");
1440 // Detect whether the cursor stands at the beginning
1441 // resp. at the end of the text.
1442 return pOutlinerView->GetSelection().IsEqual(GetSearchStartPosition ()) == TRUE;
1448 bool Outliner::HandleFailedSearch (void)
1450 bool bContinueSearch = false;
1452 OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
1453 if (pOutlinerView != NULL && mpSearchItem != NULL)
1455 // Detect whether there is/may be a prior match. If there is then
1456 // ask the user whether to wrap arround. Otherwise tell the user
1457 // that there is no match.
1458 if (HasNoPreviousMatch ())
1460 // No match found in the whole presentation. Tell the user.
1461 InfoBox aInfoBox (NULL,
1462 String(SdResId(STR_SAR_NOT_FOUND)));
1463 ShowModalMessageBox (aInfoBox);
1466 else
1468 // No further matches found. Ask the user whether to wrap
1469 // arround and start again.
1470 bContinueSearch = ShowWrapArroundDialog ();
1474 return bContinueSearch;
1478 #if ENABLE_LAYOUT
1479 #define SvxSearchDialog Window
1480 #endif
1482 /** See task #95227# for discussion about correct parent for dialogs/info boxes.
1484 ::Window* Outliner::GetParentForDialog (void)
1486 ::Window* pParent = NULL;
1488 if (meMode == SEARCH)
1489 pParent = static_cast<SvxSearchDialog*>(
1490 SfxViewFrame::Current()->GetChildWindow(
1491 SvxSearchDialogWrapper::GetChildWindowId())->GetWindow());
1493 if (pParent == NULL)
1494 pParent = mpViewShell->GetActiveWindow();
1496 if (pParent == NULL)
1497 pParent = Application::GetDefDialogParent();
1498 //1.30->1.31 of sdoutl.cxx pParent = Application::GetDefModalDialogParent();
1500 return pParent;
1503 #if ENABLE_LAYOUT
1504 #undef SvxSearchDialog
1505 #endif
1508 SdrObject* Outliner::SetObject (
1509 const ::sd::outliner::IteratorPosition& rPosition)
1511 SetViewMode (rPosition.mePageKind);
1512 SetPage (rPosition.meEditMode, (USHORT)rPosition.mnPageIndex);
1513 mnText = rPosition.mnText;
1514 return rPosition.mxObject.get();
1520 void Outliner::SetViewShell (const ::boost::shared_ptr<ViewShell>& rpViewShell)
1522 if (mpViewShell != rpViewShell)
1524 // Set the new view shell.
1525 mpViewShell = rpViewShell;
1526 // When the outline view is not owned by us then we have to clear
1527 // that pointer so that the current one for the new view shell will
1528 // be used (in ProvideOutlinerView).
1529 // if ( ! mbOwnOutlineView)
1530 // mpOutlineView = NULL;
1531 if (mpViewShell.get() != NULL)
1533 mpView = mpViewShell->GetView();
1535 mpWindow = mpViewShell->GetActiveWindow();
1537 mpImpl->ProvideOutlinerView(*this, mpViewShell, mpWindow);
1538 OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
1539 if (pOutlinerView != NULL)
1540 pOutlinerView->SetWindow(mpWindow);
1542 else
1544 mpView = NULL;
1545 mpWindow = NULL;
1553 void Outliner::HandleChangedSelection (void)
1555 maMarkListCopy.clear();
1556 mbRestrictSearchToSelection = (mpView->AreObjectsMarked()==TRUE);
1557 if (mbRestrictSearchToSelection)
1559 // Make a copy of the current mark list.
1560 const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
1561 ULONG nCount = rMarkList.GetMarkCount();
1562 if (nCount > 0)
1564 maMarkListCopy.clear();
1565 maMarkListCopy.reserve (nCount);
1566 for (ULONG i=0; i<nCount; i++)
1567 maMarkListCopy.push_back (rMarkList.GetMark(i)->GetMarkedSdrObj ());
1569 else
1570 // No marked object. Is this case possible?
1571 mbRestrictSearchToSelection = false;
1579 void Outliner::StartConversion( INT16 nSourceLanguage, INT16 nTargetLanguage,
1580 const Font *pTargetFont, INT32 nOptions, BOOL bIsInteractive )
1582 BOOL bMultiDoc = mpViewShell->ISA(DrawViewShell);
1584 meMode = TEXT_CONVERSION;
1585 mbDirectionIsForward = true;
1586 mpSearchItem = NULL;
1587 mnConversionLanguage = nSourceLanguage;
1589 BeginConversion();
1591 OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
1592 if (pOutlinerView != NULL)
1594 pOutlinerView->StartTextConversion(
1595 nSourceLanguage,
1596 nTargetLanguage,
1597 pTargetFont,
1598 nOptions,
1599 bIsInteractive,
1600 bMultiDoc);
1603 EndConversion();
1609 /** Prepare to do a text conversion on the current text object. This
1610 includes putting it into edit mode.
1612 void Outliner::PrepareConversion (void)
1614 SetUpdateMode(sal_True);
1615 if( HasConvertibleTextPortion( mnConversionLanguage ) )
1617 SetUpdateMode(sal_False);
1618 mbStringFound = TRUE;
1619 mbMatchMayExist = TRUE;
1621 EnterEditMode ();
1623 mpDrawDocument->GetDocSh()->SetWaitCursor( FALSE );
1624 // Start seach at the right end of the current object's text
1625 // depending on the search direction.
1626 // mpOutlineView->SetSelection (GetSearchStartPosition ());
1628 else
1630 SetUpdateMode(sal_False);
1637 void Outliner::BeginConversion (void)
1639 SetRefDevice( SD_MOD()->GetRefDevice( *mpDrawDocument->GetDocSh() ) );
1641 ViewShellBase* pBase = PTR_CAST(ViewShellBase, SfxViewShell::Current());
1642 if (pBase != NULL)
1643 SetViewShell (pBase->GetMainViewShell());
1645 if (mpViewShell != NULL)
1647 mbStringFound = FALSE;
1649 // Supposed that we are not located at the very beginning/end of the
1650 // document then there may be a match in the document prior/after
1651 // the current position.
1652 mbMatchMayExist = TRUE;
1654 maObjectIterator = ::sd::outliner::Iterator();
1655 maSearchStartPosition = ::sd::outliner::Iterator();
1656 RememberStartPosition();
1658 mpImpl->ProvideOutlinerView(*this, mpViewShell, mpWindow);
1660 HandleChangedSelection ();
1662 ClearModifyFlag();
1668 void Outliner::EndConversion()
1670 EndSpelling();
1676 sal_Bool Outliner::ConvertNextDocument()
1678 if( mpViewShell && mpViewShell->ISA(OutlineViewShell) )
1679 return false;
1681 mpDrawDocument->GetDocSh()->SetWaitCursor( TRUE );
1683 Initialize ( true );
1685 OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
1686 if (pOutlinerView != NULL)
1688 mpWindow = mpViewShell->GetActiveWindow();
1689 pOutlinerView->SetWindow(mpWindow);
1691 ProvideNextTextObject ();
1693 mpDrawDocument->GetDocSh()->SetWaitCursor( FALSE );
1694 ClearModifyFlag();
1696 // for text conversion we automaticly wrap around one
1697 // time and stop at the start shape
1698 if( mpFirstObj )
1700 if( (mnText == 0) && (mpFirstObj == mpObj) )
1701 return false;
1703 else
1705 mpFirstObj = mpObj;
1708 return !mbEndOfSearch;
1714 USHORT Outliner::ShowModalMessageBox (Dialog& rMessageBox)
1716 // We assume that the parent of the given messge box is NULL, i.e. it is
1717 // modal with respect to the top application window. However, this
1718 // does not affect the search dialog. Therefore we have to lock it here
1719 // while the message box is being shown. We also have to take into
1720 // account that we are called during a spell check and the search dialog
1721 // is not available.
1722 ::Window* pSearchDialog = NULL;
1723 SfxChildWindow* pChildWindow = NULL;
1724 switch (meMode)
1726 case SEARCH:
1727 pChildWindow = SfxViewFrame::Current()->GetChildWindow(
1728 SvxSearchDialogWrapper::GetChildWindowId());
1729 break;
1731 case SPELL:
1732 pChildWindow = SfxViewFrame::Current()->GetChildWindow(
1733 SpellDialogChildWindow::GetChildWindowId());
1734 break;
1736 case TEXT_CONVERSION:
1737 // There should no messages boxes be displayed while doing the
1738 // hangul hanja conversion.
1739 break;
1742 if (pChildWindow != NULL)
1743 pSearchDialog = pChildWindow->GetWindow();
1744 if (pSearchDialog != NULL)
1745 pSearchDialog->EnableInput(FALSE,TRUE);
1747 USHORT nResult = rMessageBox.Execute();
1749 // Unlock the search dialog.
1750 if (pSearchDialog != NULL)
1751 pSearchDialog->EnableInput(TRUE,TRUE);
1753 return nResult;
1759 //===== Outliner::Implementation ==============================================
1761 Outliner::Implementation::Implementation (void)
1762 : meOriginalEditMode(EM_PAGE),
1763 mbOwnOutlineView(false),
1764 mpOutlineView(NULL)
1771 Outliner::Implementation::~Implementation (void)
1773 if (mbOwnOutlineView && mpOutlineView!=NULL)
1775 mpOutlineView->SetWindow(NULL);
1776 delete mpOutlineView;
1777 mpOutlineView = NULL;
1784 OutlinerView* Outliner::Implementation::GetOutlinerView ()
1786 return mpOutlineView;
1792 /** We try to create a new OutlinerView only when there is none available,
1793 either from an OutlinerViewShell or a previous call to
1794 ProvideOutlinerView(). This is necessary to support the spell checker
1795 which can not cope with exchanging the OutlinerView.
1797 void Outliner::Implementation::ProvideOutlinerView (
1798 Outliner& rOutliner,
1799 const ::boost::shared_ptr<ViewShell>& rpViewShell,
1800 ::Window* pWindow)
1802 if (rpViewShell.get() != NULL)
1804 switch (rpViewShell->GetShellType())
1806 case ViewShell::ST_DRAW:
1807 case ViewShell::ST_IMPRESS:
1808 case ViewShell::ST_NOTES:
1809 case ViewShell::ST_HANDOUT:
1811 // Create a new outline view to do the search on.
1812 bool bInsert = false;
1813 if (mpOutlineView!=NULL && !mbOwnOutlineView)
1814 mpOutlineView = NULL;
1815 if (mpOutlineView == NULL)
1817 mpOutlineView = new OutlinerView(&rOutliner, pWindow);
1818 mbOwnOutlineView = true;
1819 bInsert = true;
1821 else
1822 mpOutlineView->SetWindow(pWindow);
1823 ULONG nStat = mpOutlineView->GetControlWord();
1824 nStat &= ~EV_CNTRL_AUTOSCROLL;
1825 mpOutlineView->SetControlWord(nStat);
1826 if (bInsert)
1827 rOutliner.InsertView( mpOutlineView );
1828 rOutliner.SetUpdateMode(FALSE);
1829 mpOutlineView->SetOutputArea (Rectangle (Point(), Size(1, 1)));
1830 rOutliner.SetPaperSize( Size(1, 1) );
1831 rOutliner.SetText( String(), rOutliner.GetParagraph( 0 ) );
1833 meOriginalEditMode =
1834 ::boost::static_pointer_cast<DrawViewShell>(rpViewShell)->GetEditMode();
1836 break;
1838 case ViewShell::ST_OUTLINE:
1840 if (mpOutlineView!=NULL && mbOwnOutlineView)
1841 delete mpOutlineView;
1842 mpOutlineView = rOutliner.GetView(0);
1843 mbOwnOutlineView = false;
1845 break;
1847 default:
1848 case ViewShell::ST_NONE:
1849 case ViewShell::ST_PRESENTATION:
1850 // Ignored
1851 break;
1859 void Outliner::Implementation::ReleaseOutlinerView (void)
1861 if (mbOwnOutlineView)
1863 OutlinerView* pView = mpOutlineView;
1864 mpOutlineView = NULL;
1865 mbOwnOutlineView = false;
1866 if (pView != NULL)
1868 pView->SetWindow(NULL);
1869 delete pView;
1872 else
1874 mpOutlineView = NULL;
1878 } // end of namespace sd