CWS-TOOLING: integrate CWS os150
[LibreOffice.git] / sd / source / ui / view / Outliner.cxx
blob29440af545bc24e2705ea21f1fe3b1df048f1df6
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
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.
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).
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.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sd.hxx"
31 #include "Outliner.hxx"
32 #include <vcl/wrkwin.hxx>
33 #include <svl/srchitem.hxx>
34 #include <editeng/colritem.hxx>
35 #include <editeng/eeitem.hxx>
36 #include <editeng/editstat.hxx>
37 #include <vcl/outdev.hxx>
38 #include <svx/dlgutil.hxx>
39 #include <svx/xtable.hxx>
40 #include <vcl/msgbox.hxx>
41 #include <sfx2/dispatch.hxx>
42 #include <sfx2/printer.hxx>
43 #include <svx/svxerr.hxx>
44 #include <svx/svdotext.hxx>
45 #include <editeng/unolingu.hxx>
46 #include <svx/svditer.hxx>
47 #include <comphelper/extract.hxx>
48 #include <com/sun/star/linguistic2/XSpellChecker1.hpp>
49 #include <com/sun/star/beans/XPropertySet.hpp>
50 #include <comphelper/processfactory.hxx>
51 #include <editeng/eeitem.hxx>
52 #include <editeng/forbiddencharacterstable.hxx>
53 #include <svx/srchdlg.hxx>
54 #include <unotools/linguprops.hxx>
55 #include <unotools/lingucfg.hxx>
56 #include <editeng/editeng.hxx>
57 #include <vcl/metric.hxx>
58 #include <sfx2/viewfrm.hxx>
59 #include <svtools/langtab.hxx>
60 #include <tools/diagnose_ex.h>
62 #include "strings.hrc"
63 #include "sdstring.hrc"
64 #include "eetext.hxx"
65 #include "sdpage.hxx"
66 #include "app.hxx"
67 #include "Window.hxx"
68 #include "sdresid.hxx"
69 #include "DrawViewShell.hxx"
70 #include "OutlineViewShell.hxx"
71 #include "drawdoc.hxx"
72 #include "DrawDocShell.hxx"
73 #include "FrameView.hxx"
74 #include "optsitem.hxx"
75 #include "drawview.hxx"
76 #include "ViewShellBase.hxx"
77 #include "SpellDialogChildWindow.hxx"
78 #include "ToolBarManager.hxx"
79 #include "framework/FrameworkHelper.hxx"
80 #include <svx/svxids.hrc>
81 #include <editeng/editerr.hxx>
83 using ::rtl::OUString;
84 using namespace ::com::sun::star;
85 using namespace ::com::sun::star::uno;
86 using namespace ::com::sun::star::lang;
87 using namespace ::com::sun::star::linguistic2;
89 class SfxStyleSheetPool;
91 namespace sd {
93 class Outliner::Implementation
95 public:
96 /** The original edit mode directly after switching to a different view
97 mode. Used for restoring the edit mode when leaving that view mode
98 again.
100 EditMode meOriginalEditMode;
102 Implementation (void);
103 ~Implementation (void);
105 /** Return the OutlinerView that was provided by the last call to
106 ProvideOutlinerView() (or NULL when there was no such call.)
108 OutlinerView* GetOutlinerView (void);
110 /** Provide in the member mpOutlineView an instance of OutlinerView that
111 is either taken from the ViewShell, when it is an OutlineViewShell,
112 or is created. When an OutlinerView already exists it is initialied.
114 void ProvideOutlinerView (
115 Outliner& rOutliner,
116 const ::boost::shared_ptr<ViewShell>& rpViewShell,
117 ::Window* pWindow);
119 /** This method is called when the OutlinerView is no longer used.
121 void ReleaseOutlinerView (void);
123 private:
124 /** Flag that specifies whether we own the outline view pointed to by
125 <member>mpOutlineView</member> and thus have to
126 delete it in <member>EndSpelling()</member>.
128 bool mbOwnOutlineView;
130 /** The outline view used for searching and spelling. If searching or
131 spell checking an outline view this data member points to that view.
132 For all other views an instance is created. The
133 <member>mbOwnOutlineView</member> distinguishes between both cases.
135 OutlinerView* mpOutlineView;
141 /*************************************************************************
143 |* Ctor
145 \************************************************************************/
147 Outliner::Outliner( SdDrawDocument* pDoc, sal_uInt16 nMode )
148 : SdrOutliner( &pDoc->GetItemPool(), nMode ),
149 mpImpl(new Implementation()),
150 meMode(SEARCH),
151 mpView(NULL),
152 mpViewShell(),
153 mpWindow(NULL),
154 mpDrawDocument(pDoc),
155 mnConversionLanguage(LANGUAGE_NONE),
156 mnIgnoreCurrentPageChangesLevel(0),
157 mbStringFound(sal_False),
158 mbMatchMayExist(false),
159 mnPageCount(0),
160 mnObjectCount(0),
161 mbEndOfSearch(sal_False),
162 mbFoundObject(sal_False),
163 mbError(sal_False),
164 mbDirectionIsForward(true),
165 mbRestrictSearchToSelection(false),
166 maMarkListCopy(),
167 mbProcessCurrentViewOnly(false),
168 mpObj(NULL),
169 mpFirstObj(NULL),
170 mpTextObj(NULL),
171 mnText(0),
172 mpParaObj(NULL),
173 meStartViewMode(PK_STANDARD),
174 meStartEditMode(EM_PAGE),
175 mnStartPageIndex((sal_uInt16)-1),
176 mpStartEditedObject(NULL),
177 maStartSelection(),
178 mpSearchItem(NULL),
179 maObjectIterator(),
180 maCurrentPosition(),
181 maSearchStartPosition(),
182 maLastValidPosition(),
183 mbSelectionHasChanged(false),
184 mbExpectingSelectionChangeEvent(false),
185 mbWholeDocumentProcessed(false),
186 mbPrepareSpellingPending(true),
187 mbViewShellValid(true)
189 SetStyleSheetPool((SfxStyleSheetPool*) mpDrawDocument->GetStyleSheetPool());
190 SetEditTextObjectPool( &pDoc->GetItemPool() );
191 SetCalcFieldValueHdl(LINK(SD_MOD(), SdModule, CalcFieldValueHdl));
192 SetForbiddenCharsTable( pDoc->GetForbiddenCharsTable() );
194 sal_uLong nCntrl = GetControlWord();
195 nCntrl |= EE_CNTRL_ALLOWBIGOBJS;
196 nCntrl |= EE_CNTRL_URLSFXEXECUTE;
197 nCntrl |= EE_CNTRL_MARKFIELDS;
198 nCntrl |= EE_CNTRL_AUTOCORRECT;
200 sal_Bool bOnlineSpell = false;
202 DrawDocShell* pDocSh = mpDrawDocument->GetDocSh();
204 if (pDocSh)
206 bOnlineSpell = mpDrawDocument->GetOnlineSpell();
208 else
210 bOnlineSpell = false;
214 const SvtLinguConfig aLinguConfig;
215 Any aAny;
217 aAny = aLinguConfig.GetProperty(
218 rtl::OUString::createFromAscii( UPN_IS_SPELL_AUTO ) );
219 aAny >>= bOnlineSpell;
221 catch( ... )
223 DBG_ERROR( "Ill. type in linguistic property" );
227 if (bOnlineSpell)
228 nCntrl |= EE_CNTRL_ONLINESPELLING;
229 else
230 nCntrl &= ~EE_CNTRL_ONLINESPELLING;
232 SetControlWord(nCntrl);
234 Reference< XSpellChecker1 > xSpellChecker( LinguMgr::GetSpellChecker() );
235 if ( xSpellChecker.is() )
236 SetSpeller( xSpellChecker );
238 Reference< XHyphenator > xHyphenator( LinguMgr::GetHyphenator() );
239 if( xHyphenator.is() )
240 SetHyphenator( xHyphenator );
242 SetDefaultLanguage( Application::GetSettings().GetLanguage() );
248 /// Nothing spectecular in the destructor.
249 Outliner::~Outliner (void)
251 mpImpl.reset();
257 /** Prepare find&replace or spellchecking. This distinguishes between three
258 cases:
259 <ol>
260 <li>The current shell is a <type>DrawViewShell</type>: Create a
261 <type>OutlinerView</type> object and search all objects of (i) the
262 current mark list, (ii) of the current view, or (iii) of all the view
263 combinations:
264 <ol>
265 <li>Draw view, slide view</li>
266 <li>Draw view, background view</li>
267 <li>Notes view, slide view</li>
268 <li>Notes view, background view</li>
269 <li>Handout view, slide view</li>
270 <li>Handout view, background view</li>
271 </ol>
273 <li>When the current shell is a <type>SdOutlineViewShell</type> then
274 directly operate on it. No switching into other views takes place.</li>
276 <li>For a <type>SlideViewShell</type> no action is performed.</li>
277 </ol>
279 void Outliner::PrepareSpelling (void)
281 if (mbViewShellValid)
283 mbPrepareSpellingPending = false;
285 ViewShellBase* pBase = PTR_CAST(ViewShellBase,SfxViewShell::Current());
286 if (pBase != NULL)
287 SetViewShell (pBase->GetMainViewShell());
288 SetRefDevice( SD_MOD()->GetRefDevice( *mpDrawDocument->GetDocSh() ) );
290 if (mpViewShell.get() != NULL)
292 mbStringFound = sal_False;
294 mbWholeDocumentProcessed = false;
295 // Supposed that we are not located at the very beginning/end of
296 // the document then there may be a match in the document
297 // prior/after the current position.
298 mbMatchMayExist = sal_True;
300 maObjectIterator = ::sd::outliner::Iterator();
301 maSearchStartPosition = ::sd::outliner::Iterator();
302 RememberStartPosition();
304 mpImpl->ProvideOutlinerView(*this, mpViewShell, mpWindow);
306 HandleChangedSelection ();
308 ClearModifyFlag();
316 void Outliner::StartSpelling (void)
318 meMode = SPELL;
319 mbDirectionIsForward = true;
320 mpSearchItem = NULL;
323 /** Proxy for method from base class to avoid compiler warning */
324 void Outliner::StartSpelling(EditView& rView, unsigned char c)
326 SdrOutliner::StartSpelling( rView, c );
329 /** Free all resources acquired during the search/spell check. After a
330 spell check the start position is restored here.
332 void Outliner::EndSpelling (void)
334 if (mbViewShellValid)
336 // Keep old view shell alive until we release the outliner view.
337 ::boost::shared_ptr<ViewShell> pOldViewShell (mpViewShell);
339 ViewShellBase* pBase = PTR_CAST(ViewShellBase,SfxViewShell::Current());
340 if (pBase != NULL)
341 mpViewShell = pBase->GetMainViewShell();
342 else
343 mpViewShell.reset();
345 // When in <member>PrepareSpelling()</member> a new outline view has
346 // been created then delete it here.
347 sal_Bool bViewIsDrawViewShell(mpViewShell.get()!=NULL
348 && mpViewShell->ISA(DrawViewShell));
349 if (bViewIsDrawViewShell)
351 SetStatusEventHdl(Link());
352 mpView = mpViewShell->GetView();
353 mpView->UnmarkAllObj (mpView->GetSdrPageView());
354 mpView->SdrEndTextEdit();
355 // Make FuSelection the current function.
356 mpViewShell->GetDispatcher()->Execute(
357 SID_OBJECT_SELECT,
358 SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD);
360 // Remove and, if previously created by us, delete the outline
361 // view.
362 OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
363 if (pOutlinerView != NULL)
365 RemoveView(pOutlinerView);
366 mpImpl->ReleaseOutlinerView();
369 SetUpdateMode(sal_True);
372 // #95811# Before clearing the modify flag use it as a hint that
373 // changes were done at SpellCheck
374 if(IsModified())
376 if(mpView && mpView->ISA(OutlineView))
377 static_cast<OutlineView*>(mpView)->PrepareClose(sal_False);
378 if(mpDrawDocument && !mpDrawDocument->IsChanged())
379 mpDrawDocument->SetChanged(sal_True);
382 // #95811# now clear the modify flag to have a specified state of
383 // Outliner
384 ClearModifyFlag();
386 // When spell checking then restore the start position.
387 if (meMode==SPELL || meMode==TEXT_CONVERSION)
388 RestoreStartPosition ();
391 mpViewShell.reset();
392 mpView = NULL;
393 mpWindow = NULL;
399 sal_Bool Outliner::SpellNextDocument (void)
401 if (mpViewShell->ISA(OutlineViewShell))
403 // When doing a spell check in the outline view then there is
404 // only one document.
405 mbEndOfSearch = true;
406 EndOfSearch ();
408 else
410 if (mpView->ISA(OutlineView))
411 ((OutlineView*)mpView)->PrepareClose(sal_False);
412 mpDrawDocument->GetDocSh()->SetWaitCursor( sal_True );
414 Initialize (true);
416 mpWindow = mpViewShell->GetActiveWindow();
417 OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
418 if (pOutlinerView != NULL)
419 pOutlinerView->SetWindow(mpWindow);
420 ProvideNextTextObject ();
422 mpDrawDocument->GetDocSh()->SetWaitCursor( sal_False );
423 ClearModifyFlag();
426 return mbEndOfSearch ? sal_False : sal_True;
431 /*************************************************************************
433 |* Spelling: naechstes TextObjekt pruefen
435 \************************************************************************/
437 ::svx::SpellPortions Outliner::GetNextSpellSentence (void)
439 ::svx::SpellPortions aResult;
441 DetectChange();
442 // Iterate over sentences and text shapes until a sentence with a
443 // spelling error has been found. If no such sentence can be
444 // found the loop is left through a break.
445 // It is the responsibility of the sd outliner object to correctly
446 // iterate over all text shapes, i.e. switch between views, wrap
447 // arround at the end of the document, stop when all text shapes
448 // have been examined exactly once.
449 bool bFoundNextSentence = false;
450 while ( ! bFoundNextSentence)
452 OutlinerView* pOutlinerView = GetView(0);
453 if (pOutlinerView != NULL)
455 ESelection aCurrentSelection (pOutlinerView->GetSelection());
456 if ( ! mbMatchMayExist
457 && maStartSelection.IsLess(aCurrentSelection))
458 EndOfSearch();
460 // Advance to the next sentence.
461 bFoundNextSentence = SpellSentence (
462 pOutlinerView->GetEditView(),
463 aResult, false);
466 // When no sentence with spelling errors has been found in the
467 // currently selected text shape or there is no selected text
468 // shape then advance to the next text shape.
469 if ( ! bFoundNextSentence)
470 if ( ! SpellNextDocument())
471 // All text objects have been processed so exit the
472 // loop and return an empty portions list.
473 break;
476 return aResult;
482 /** Go to next match.
484 bool Outliner::StartSearchAndReplace (const SvxSearchItem* pSearchItem)
486 sal_Bool bEndOfSearch = sal_True;
488 if (mbViewShellValid)
490 mpDrawDocument->GetDocSh()->SetWaitCursor( sal_True );
491 if (mbPrepareSpellingPending)
492 PrepareSpelling();
493 ViewShellBase* pBase = PTR_CAST(ViewShellBase,SfxViewShell::Current());
494 // Determine whether we have to abort the search. This is necessary
495 // when the main view shell does not support searching.
496 bool bAbort = false;
497 if (pBase != NULL)
499 ::boost::shared_ptr<ViewShell> pShell (pBase->GetMainViewShell());
500 SetViewShell(pShell);
501 if (pShell.get() == NULL)
502 bAbort = true;
503 else
504 switch (pShell->GetShellType())
506 case ViewShell::ST_DRAW:
507 case ViewShell::ST_IMPRESS:
508 case ViewShell::ST_NOTES:
509 case ViewShell::ST_HANDOUT:
510 case ViewShell::ST_OUTLINE:
511 bAbort = false;
512 break;
513 default:
514 bAbort = true;
515 break;
519 if ( ! bAbort)
521 meMode = SEARCH;
522 mpSearchItem = pSearchItem;
524 mbFoundObject = sal_False;
526 Initialize ( ! mpSearchItem->GetBackward());
528 sal_uInt16 nCommand = mpSearchItem->GetCommand();
529 if (nCommand == SVX_SEARCHCMD_REPLACE_ALL)
530 bEndOfSearch = SearchAndReplaceAll ();
531 else
533 RememberStartPosition ();
534 bEndOfSearch = SearchAndReplaceOnce ();
535 //#107233# restore start position if nothing was found
536 if(!mbStringFound)
537 RestoreStartPosition ();
538 else
539 mnStartPageIndex = (sal_uInt16)-1;
542 else
543 mpDrawDocument->GetDocSh()->SetWaitCursor( sal_False );
546 return bEndOfSearch;
552 void Outliner::Initialize (bool bDirectionIsForward)
554 const bool bIsAtEnd (maObjectIterator == ::sd::outliner::OutlinerContainer(this).end());
555 const bool bOldDirectionIsForward = mbDirectionIsForward;
556 mbDirectionIsForward = bDirectionIsForward;
558 if (maObjectIterator == ::sd::outliner::Iterator())
560 // Initialize a new search.
561 maObjectIterator = ::sd::outliner::OutlinerContainer(this).current();
562 maCurrentPosition = *maObjectIterator;
564 // In case we are searching in an outline view then first remove the
565 // current selection and place cursor at its start or end.
566 if (mpViewShell->ISA(OutlineViewShell))
568 ESelection aSelection = mpImpl->GetOutlinerView()->GetSelection ();
569 if (mbDirectionIsForward)
571 aSelection.nEndPara = aSelection.nStartPara;
572 aSelection.nEndPos = aSelection.nStartPos;
574 else
576 aSelection.nStartPara = aSelection.nEndPara;
577 aSelection.nStartPos = aSelection.nEndPos;
579 mpImpl->GetOutlinerView()->SetSelection (aSelection);
582 // When not beginning the search at the beginning of the search area
583 // then there may be matches before the current position.
584 mbMatchMayExist = (maObjectIterator!=::sd::outliner::OutlinerContainer(this).begin());
586 else if (bOldDirectionIsForward != mbDirectionIsForward)
588 // Requested iteration direction has changed. Turn arround the iterator.
589 maObjectIterator.Reverse();
590 if (bIsAtEnd)
592 // The iterator has pointed to end(), which after the search
593 // direction is reversed, becomes begin().
594 maObjectIterator = ::sd::outliner::OutlinerContainer(this).begin();
596 else
598 // The iterator has pointed to the object one ahead/before the current
599 // one. Now move it to the one before/ahead the current one.
600 ++maObjectIterator;
601 ++maObjectIterator;
604 mbMatchMayExist = true;
607 // Initialize the last valid position with where the search starts so
608 // that it always points to a valid position.
609 maLastValidPosition = *::sd::outliner::OutlinerContainer(this).current();
615 bool Outliner::SearchAndReplaceAll (void)
617 // Save the current position to be restored after having replaced all
618 // matches.
619 RememberStartPosition ();
621 if (mpViewShell->ISA(OutlineViewShell))
623 // Put the cursor to the beginning/end of the outliner.
624 mpImpl->GetOutlinerView()->SetSelection (GetSearchStartPosition ());
626 // The outliner does all the work for us when we are in this mode.
627 SearchAndReplaceOnce();
629 else if (mpViewShell->ISA(DrawViewShell))
631 // Go to beginning/end of document.
632 maObjectIterator = ::sd::outliner::OutlinerContainer(this).begin();
633 // Switch to the current object only if it is a valid text object.
634 ::sd::outliner::IteratorPosition aNewPosition (*maObjectIterator);
635 if (IsValidTextObject (aNewPosition))
637 maCurrentPosition = aNewPosition;
638 SetObject (maCurrentPosition);
641 // Search/replace until the end of the document is reached.
642 bool bFoundMatch;
645 bFoundMatch = ! SearchAndReplaceOnce();
647 while (bFoundMatch);
650 RestoreStartPosition ();
652 return true;
658 bool Outliner::SearchAndReplaceOnce (void)
660 DetectChange ();
662 OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
663 DBG_ASSERT(pOutlinerView!=NULL && GetEditEngine().HasView( &pOutlinerView->GetEditView() ),
664 "SearchAndReplace without valid view!" );
666 if( NULL == pOutlinerView || !GetEditEngine().HasView( &pOutlinerView->GetEditView() ) )
667 return true;
669 if (mpViewShell != NULL)
671 mpView = mpViewShell->GetView();
672 mpWindow = mpViewShell->GetActiveWindow();
673 pOutlinerView->SetWindow(mpWindow);
675 if (mpViewShell->ISA(DrawViewShell) )
677 // When replacing we first check if there is a selection
678 // indicating a match. If there is then replace it. The
679 // following call to StartSearchAndReplace will then search for
680 // the next match.
681 if (meMode == SEARCH
682 && mpSearchItem->GetCommand() == SVX_SEARCHCMD_REPLACE)
683 if (pOutlinerView->GetSelection().HasRange())
684 pOutlinerView->StartSearchAndReplace(*mpSearchItem);
686 // Search for the next match.
687 sal_uLong nMatchCount = 0;
688 if (mpSearchItem->GetCommand() != SVX_SEARCHCMD_REPLACE_ALL)
689 nMatchCount = pOutlinerView->StartSearchAndReplace(*mpSearchItem);
691 // Go to the next text object when there have been no matches in
692 // the current object or the whole object has already been
693 // processed.
694 if (nMatchCount==0 || mpSearchItem->GetCommand()==SVX_SEARCHCMD_REPLACE_ALL)
696 ProvideNextTextObject ();
698 if ( ! mbEndOfSearch)
700 // Remember the current position as the last one with a
701 // text object.
702 maLastValidPosition = maCurrentPosition;
704 // Now that the mbEndOfSearch flag guards this block the
705 // following assertion and return should not be
706 // necessary anymore.
707 DBG_ASSERT(GetEditEngine().HasView(&pOutlinerView->GetEditView() ),
708 "SearchAndReplace without valid view!" );
709 if ( ! GetEditEngine().HasView( &pOutlinerView->GetEditView() ) )
711 mpDrawDocument->GetDocSh()->SetWaitCursor( sal_False );
712 return true;
715 if (meMode == SEARCH)
716 nMatchCount = pOutlinerView->StartSearchAndReplace(*mpSearchItem);
720 else if (mpViewShell->ISA(OutlineViewShell))
722 mpDrawDocument->GetDocSh()->SetWaitCursor (sal_False);
723 // The following loop is executed more then once only when a
724 // wrap arround search is done.
725 while (true)
727 int nResult = pOutlinerView->StartSearchAndReplace(*mpSearchItem);
728 if (nResult == 0)
730 if (HandleFailedSearch ())
732 pOutlinerView->SetSelection (GetSearchStartPosition ());
733 continue;
736 else
737 mbStringFound = true;
738 break;
743 mpDrawDocument->GetDocSh()->SetWaitCursor( sal_False );
745 return mbEndOfSearch;
751 /** Try to detect whether the document or the view (shell) has changed since
752 the last time <member>StartSearchAndReplace()</member> has been called.
754 void Outliner::DetectChange (void)
756 ::sd::outliner::IteratorPosition aPosition (maCurrentPosition);
758 ::boost::shared_ptr<DrawViewShell> pDrawViewShell (
759 ::boost::dynamic_pointer_cast<DrawViewShell>(mpViewShell));
761 // Detect whether the view has been switched from the outside.
762 if (pDrawViewShell.get() != NULL
763 && (aPosition.meEditMode != pDrawViewShell->GetEditMode()
764 || aPosition.mePageKind != pDrawViewShell->GetPageKind()))
766 // Either the edit mode or the page kind has changed.
767 SetStatusEventHdl(Link());
769 SdrPageView* pPageView = mpView->GetSdrPageView();
770 if (pPageView != NULL)
771 mpView->UnmarkAllObj (pPageView);
772 mpView->SdrEndTextEdit();
773 SetUpdateMode(sal_False);
774 OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
775 if (pOutlinerView != NULL)
776 pOutlinerView->SetOutputArea( Rectangle( Point(), Size(1, 1) ) );
777 if (meMode == SPELL)
778 SetPaperSize( Size(1, 1) );
779 SetText( String(), GetParagraph( 0 ) );
781 RememberStartPosition ();
783 mnPageCount = mpDrawDocument->GetSdPageCount(pDrawViewShell->GetPageKind());
784 maObjectIterator = ::sd::outliner::OutlinerContainer(this).current();
787 // Detect change of the set of selected objects. If their number has
788 // changed start again with the first selected object.
789 else if (DetectSelectionChange())
791 HandleChangedSelection ();
792 maObjectIterator = ::sd::outliner::OutlinerContainer(this).current();
795 // Detect change of page count. Restart search at first/last page in
796 // that case.
797 else if (aPosition.meEditMode == EM_PAGE
798 && mpDrawDocument->GetSdPageCount(aPosition.mePageKind) != mnPageCount)
800 // The number of pages has changed.
801 mnPageCount = mpDrawDocument->GetSdPageCount(aPosition.mePageKind);
802 maObjectIterator = ::sd::outliner::OutlinerContainer(this).current();
804 else if (aPosition.meEditMode == EM_MASTERPAGE
805 && mpDrawDocument->GetSdPageCount(aPosition.mePageKind) != mnPageCount)
807 // The number of master pages has changed.
808 mnPageCount = mpDrawDocument->GetSdPageCount(aPosition.mePageKind);
809 maObjectIterator = ::sd::outliner::OutlinerContainer(this).current();
816 bool Outliner::DetectSelectionChange (void)
818 bool bSelectionHasChanged = false;
819 sal_uLong nMarkCount = mpView->GetMarkedObjectList().GetMarkCount();
821 // If mpObj is NULL then we have not yet found our first match.
822 // Detecting a change makes no sense.
823 if (mpObj != NULL)
824 switch (nMarkCount)
826 case 0:
827 // The selection has changed when previously there have been
828 // selected objects.
829 bSelectionHasChanged = mbRestrictSearchToSelection;
830 break;
831 case 1:
832 // Check if the only selected object is not the one that we
833 // had selected.
834 if (mpView != NULL)
836 SdrMark* pMark = mpView->GetMarkedObjectList().GetMark(0);
837 if (pMark != NULL)
838 bSelectionHasChanged = (mpObj != pMark->GetMarkedSdrObj ());
840 break;
841 default:
842 // We had selected exactly one object.
843 bSelectionHasChanged = true;
844 break;
847 return bSelectionHasChanged;
853 void Outliner::RememberStartPosition (void)
855 if (mpViewShell->ISA(DrawViewShell))
857 ::boost::shared_ptr<DrawViewShell> pDrawViewShell (
858 ::boost::dynamic_pointer_cast<DrawViewShell>(mpViewShell));
859 if (pDrawViewShell.get() != NULL)
861 meStartViewMode = pDrawViewShell->GetPageKind();
862 meStartEditMode = pDrawViewShell->GetEditMode();
863 mnStartPageIndex = pDrawViewShell->GetCurPageId() - 1;
866 if (mpView != NULL)
868 mpStartEditedObject = mpView->GetTextEditObject();
869 if (mpStartEditedObject != NULL)
871 // Try to retrieve current caret position only when there is an
872 // edited object.
873 ::Outliner* pOutliner =
874 static_cast<DrawView*>(mpView)->GetTextEditOutliner();
875 if (pOutliner!=NULL && pOutliner->GetViewCount()>0)
877 OutlinerView* pOutlinerView = pOutliner->GetView(0);
878 maStartSelection = pOutlinerView->GetSelection();
883 else if (mpViewShell->ISA(OutlineViewShell))
885 // Remember the current cursor position.
886 OutlinerView* pView = GetView(0);
887 if (pView != NULL)
888 pView->GetSelection();
890 else
892 mnStartPageIndex = (sal_uInt16)-1;
899 void Outliner::RestoreStartPosition (void)
901 bool bRestore = true;
902 // Take a negative start page index as inidicator that restoring the
903 // start position is not requested.
904 if (mnStartPageIndex == (sal_uInt16)-1 )
905 bRestore = false;
906 // Dont't resore when the view shell is not valid.
907 if (mpViewShell == NULL)
908 bRestore = false;
909 if ( ! mbViewShellValid)
910 bRestore = false;
912 if (bRestore)
914 if (mpViewShell->ISA(DrawViewShell))
916 ::boost::shared_ptr<DrawViewShell> pDrawViewShell (
917 ::boost::dynamic_pointer_cast<DrawViewShell>(mpViewShell));
918 SetViewMode (meStartViewMode);
919 if (pDrawViewShell.get() != NULL)
920 SetPage (meStartEditMode, mnStartPageIndex);
923 if (mpStartEditedObject != NULL)
925 // Turn on the text toolbar as it is done in FuText so that
926 // undo manager setting/restoring in
927 // sd::View::{Beg,End}TextEdit() works on the same view shell.
928 mpViewShell->GetViewShellBase().GetToolBarManager()->SetToolBarShell(
929 ToolBarManager::TBG_FUNCTION,
930 RID_DRAW_TEXT_TOOLBOX);
932 mpView->SdrBeginTextEdit(mpStartEditedObject);
933 ::Outliner* pOutliner =
934 static_cast<DrawView*>(mpView)->GetTextEditOutliner();
935 if (pOutliner!=NULL && pOutliner->GetViewCount()>0)
937 OutlinerView* pOutlinerView = pOutliner->GetView(0);
938 pOutlinerView->SetSelection(maStartSelection);
942 else if (mpViewShell->ISA(OutlineViewShell))
944 // Set cursor to its old position.
945 OutlinerView* pView = GetView(0);
946 if (pView != NULL)
947 pView->SetSelection (maStartSelection);
955 /** The main purpose of this method is to iterate over all shape objects of
956 the search area (current selection, current view, or whole document)
957 until a text object has been found that contains at least one match or
958 until no such object can be found anymore. These two conditions are
959 expressed by setting one of the flags <member>mbFoundObject</member> or
960 <member>mbEndOfSearch</member> to <TRUE/>.
962 void Outliner::ProvideNextTextObject (void)
964 mbEndOfSearch = false;
965 mbFoundObject = false;
967 mpView->UnmarkAllObj (mpView->GetSdrPageView());
970 mpView->SdrEndTextEdit();
972 catch (::com::sun::star::uno::Exception e)
974 DBG_UNHANDLED_EXCEPTION();
976 SetUpdateMode(sal_False);
977 OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
978 if (pOutlinerView != NULL)
979 pOutlinerView->SetOutputArea( Rectangle( Point(), Size(1, 1) ) );
980 if (meMode == SPELL)
981 SetPaperSize( Size(1, 1) );
982 SetText( String(), GetParagraph( 0 ) );
984 mpTextObj = NULL;
986 // Iterate until a valid text object has been found or the search ends.
989 mpObj = NULL;
990 mpParaObj = NULL;
992 if (maObjectIterator != ::sd::outliner::OutlinerContainer(this).end())
994 maCurrentPosition = *maObjectIterator;
995 // Switch to the current object only if it is a valid text object.
996 if (IsValidTextObject (maCurrentPosition))
998 mpObj = SetObject (maCurrentPosition);
1000 ++maObjectIterator;
1002 if (mpObj != NULL)
1004 PutTextIntoOutliner ();
1006 if (mpViewShell != NULL)
1007 switch (meMode)
1009 case SEARCH:
1010 PrepareSearchAndReplace ();
1011 break;
1012 case SPELL:
1013 PrepareSpellCheck ();
1014 break;
1015 case TEXT_CONVERSION:
1016 PrepareConversion();
1017 break;
1021 else
1023 mbEndOfSearch = true;
1024 EndOfSearch ();
1027 while ( ! (mbFoundObject || mbEndOfSearch));
1033 void Outliner::EndOfSearch (void)
1035 // Before we display a dialog we first jump to where the last valid text
1036 // object was found. All page and view mode switching since then was
1037 // temporary and should not be visible to the user.
1038 if ( ! mpViewShell->ISA(OutlineViewShell))
1039 SetObject (maLastValidPosition);
1041 if (mbRestrictSearchToSelection)
1042 ShowEndOfSearchDialog ();
1043 else
1045 // When no match has been found so far then terminate the search.
1046 if ( ! mbMatchMayExist)
1048 ShowEndOfSearchDialog ();
1049 mbEndOfSearch = sal_True;
1051 // Ask the user whether to wrap arround and continue the search or
1052 // to terminate.
1053 else if (meMode==TEXT_CONVERSION || ShowWrapArroundDialog ())
1055 mbMatchMayExist = false;
1056 // Everything back to beginning (or end?) of the document.
1057 maObjectIterator = ::sd::outliner::OutlinerContainer(this).begin();
1058 if (mpViewShell->ISA(OutlineViewShell))
1060 // Set cursor to first character of the document.
1061 OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
1062 if (pOutlinerView != NULL)
1063 pOutlinerView->SetSelection (GetSearchStartPosition ());
1066 mbEndOfSearch = false;
1068 else
1070 // No wrap arround.
1071 mbEndOfSearch = true;
1076 void Outliner::ShowEndOfSearchDialog (void)
1078 String aString;
1079 if (meMode == SEARCH)
1081 if (mbStringFound)
1082 aString = String( SdResId(STR_END_SEARCHING) );
1083 else
1084 aString = String( SdResId(STR_STRING_NOTFOUND) );
1086 else
1088 if (mpView->AreObjectsMarked())
1089 aString = String(SdResId(STR_END_SPELLING_OBJ));
1090 else
1091 aString = String(SdResId(STR_END_SPELLING));
1094 // Show the message in an info box that is modal with respect to the
1095 // whole application.
1096 InfoBox aInfoBox (NULL, aString);
1097 ShowModalMessageBox (aInfoBox);
1099 mbWholeDocumentProcessed = true;
1105 bool Outliner::ShowWrapArroundDialog (void)
1107 bool bDoWrapArround = false;
1109 // Determine whether to show the dialog.
1110 bool bShowDialog = false;
1111 if (mpSearchItem != NULL)
1113 // When searching display the dialog only for single find&replace.
1114 sal_uInt16 nCommand = mpSearchItem->GetCommand();
1115 bShowDialog = (nCommand==SVX_SEARCHCMD_REPLACE)
1116 || (nCommand==SVX_SEARCHCMD_FIND);
1118 else
1119 // Spell checking needs the dialog, too.
1120 bShowDialog = (meMode == SPELL);
1122 if (bShowDialog)
1124 // The question text depends on the search direction.
1125 sal_Bool bImpress = mpDrawDocument!=NULL
1126 && mpDrawDocument->GetDocumentType() == DOCUMENT_TYPE_IMPRESS;
1127 sal_uInt16 nStringId;
1128 if (mbDirectionIsForward)
1129 nStringId = bImpress
1130 ? STR_SAR_WRAP_FORWARD
1131 : STR_SAR_WRAP_FORWARD_DRAW;
1132 else
1133 nStringId = bImpress
1134 ? STR_SAR_WRAP_BACKWARD
1135 : STR_SAR_WRAP_BACKWARD_DRAW;
1137 // Pop up question box that asks the user whether to wrap arround.
1138 // The dialog is made modal with respect to the whole application.
1139 QueryBox aQuestionBox (
1140 NULL,
1141 WB_YES_NO | WB_DEF_YES,
1142 String(SdResId(nStringId)));
1143 aQuestionBox.SetImage (QueryBox::GetStandardImage());
1144 sal_uInt16 nBoxResult = ShowModalMessageBox(aQuestionBox);
1145 bDoWrapArround = (nBoxResult == BUTTONID_YES);
1148 return bDoWrapArround;
1154 bool Outliner::IsValidTextObject (const ::sd::outliner::IteratorPosition& rPosition)
1156 SdrTextObj* pObject = dynamic_cast< SdrTextObj* >( rPosition.mxObject.get() );
1157 return (pObject != NULL) && pObject->HasText() && ! pObject->IsEmptyPresObj();
1163 void Outliner::PutTextIntoOutliner()
1165 mpTextObj = dynamic_cast<SdrTextObj*>( mpObj );
1166 if ( mpTextObj && mpTextObj->HasText() && !mpTextObj->IsEmptyPresObj() )
1168 SdrText* pText = mpTextObj->getText( mnText );
1169 mpParaObj = pText ? pText->GetOutlinerParaObject() : NULL;
1171 if (mpParaObj != NULL)
1173 SetText(*mpParaObj);
1175 ClearModifyFlag();
1178 else
1180 mpTextObj = NULL;
1187 void Outliner::PrepareSpellCheck (void)
1189 EESpellState eState = HasSpellErrors();
1190 DBG_ASSERT(eState != EE_SPELL_NOSPELLER, "No SpellChecker");
1192 if (eState == EE_SPELL_NOLANGUAGE)
1194 mbError = sal_True;
1195 mbEndOfSearch = sal_True;
1196 ErrorBox aErrorBox (NULL,
1197 WB_OK,
1198 String(SdResId(STR_NOLANGUAGE)));
1199 ShowModalMessageBox (aErrorBox);
1201 else if (eState != EE_SPELL_OK)
1203 // When spell checking we have to test whether we have processed the
1204 // whole document and have reached the start page again.
1205 if (meMode == SPELL)
1207 if (maSearchStartPosition == ::sd::outliner::Iterator())
1208 // Remember the position of the first text object so that we
1209 // know when we have processed the whole document.
1210 maSearchStartPosition = maObjectIterator;
1211 else if (maSearchStartPosition == maObjectIterator)
1213 mbEndOfSearch = true;
1217 EnterEditMode( sal_False );
1224 void Outliner::PrepareSearchAndReplace (void)
1226 if (HasText( *mpSearchItem ))
1228 mbStringFound = true;
1229 mbMatchMayExist = true;
1231 EnterEditMode ();
1233 mpDrawDocument->GetDocSh()->SetWaitCursor( sal_False );
1234 // Start seach at the right end of the current object's text
1235 // depending on the search direction.
1236 OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
1237 if (pOutlinerView != NULL)
1238 pOutlinerView->SetSelection (GetSearchStartPosition ());
1245 void Outliner::SetViewMode (PageKind ePageKind)
1247 ::boost::shared_ptr<DrawViewShell> pDrawViewShell(
1248 ::boost::dynamic_pointer_cast<DrawViewShell>(mpViewShell));
1249 if (pDrawViewShell.get()!=NULL && ePageKind != pDrawViewShell->GetPageKind())
1251 // Restore old edit mode.
1252 pDrawViewShell->ChangeEditMode(mpImpl->meOriginalEditMode, sal_False);
1254 SetStatusEventHdl(Link());
1255 ::rtl::OUString sViewURL;
1256 switch (ePageKind)
1258 case PK_STANDARD:
1259 default:
1260 sViewURL = framework::FrameworkHelper::msImpressViewURL;
1261 break;
1262 case PK_NOTES:
1263 sViewURL = framework::FrameworkHelper::msNotesViewURL;
1264 break;
1265 case PK_HANDOUT:
1266 sViewURL = framework::FrameworkHelper::msHandoutViewURL;
1267 break;
1269 // The text object iterator is destroyed when the shells are
1270 // switched but we need it so save it and restore it afterwards.
1271 ::sd::outliner::Iterator aIterator (maObjectIterator);
1272 bool bMatchMayExist = mbMatchMayExist;
1274 ViewShellBase& rBase = mpViewShell->GetViewShellBase();
1275 SetViewShell(::boost::shared_ptr<ViewShell>());
1276 framework::FrameworkHelper::Instance(rBase)->RequestView(
1277 sViewURL,
1278 framework::FrameworkHelper::msCenterPaneURL);
1280 // Force (well, request) a synchronous update of the configuration.
1281 // In a better world we would handle the asynchronous view update
1282 // instead. But that would involve major restucturing of the
1283 // Outliner code.
1284 framework::FrameworkHelper::Instance(rBase)->RequestSynchronousUpdate();
1285 SetViewShell(rBase.GetMainViewShell());
1287 // Switching to another view shell has intermediatly called
1288 // EndSpelling(). A PrepareSpelling() is pending, so call that now.
1289 PrepareSpelling();
1291 // Update the number of pages so that
1292 // <member>DetectChange()</member> has the correct value to compare
1293 // to.
1294 mnPageCount = mpDrawDocument->GetSdPageCount(ePageKind);
1296 maObjectIterator = aIterator;
1297 mbMatchMayExist = bMatchMayExist;
1299 // Save edit mode so that it can be restored when switching the view
1300 // shell again.
1301 pDrawViewShell = ::boost::dynamic_pointer_cast<DrawViewShell>(mpViewShell);
1302 OSL_ASSERT(pDrawViewShell.get()!=NULL);
1303 if (pDrawViewShell.get() != NULL)
1304 mpImpl->meOriginalEditMode = pDrawViewShell->GetEditMode();
1311 void Outliner::SetPage (EditMode eEditMode, sal_uInt16 nPageIndex)
1313 if ( ! mbRestrictSearchToSelection)
1315 ::boost::shared_ptr<DrawViewShell> pDrawViewShell(
1316 ::boost::dynamic_pointer_cast<DrawViewShell>(mpViewShell));
1317 OSL_ASSERT(pDrawViewShell.get()!=NULL);
1318 if (pDrawViewShell.get() != NULL)
1320 pDrawViewShell->ChangeEditMode(eEditMode, sal_False);
1321 pDrawViewShell->SwitchPage(nPageIndex);
1329 void Outliner::EnterEditMode (sal_Bool bGrabFocus)
1331 OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
1332 if (mbViewShellValid && pOutlinerView != NULL)
1334 pOutlinerView->SetOutputArea( Rectangle( Point(), Size(1, 1)));
1335 SetPaperSize( mpTextObj->GetLogicRect().GetSize() );
1336 SdrPageView* pPV = mpView->GetSdrPageView();
1338 // Make FuText the current function.
1339 SfxUInt16Item aItem (SID_TEXTEDIT, 1);
1340 mpViewShell->GetDispatcher()->
1341 Execute(SID_TEXTEDIT, SFX_CALLMODE_SYNCHRON |
1342 SFX_CALLMODE_RECORD, &aItem, 0L);
1344 // To be consistent with the usual behaviour in the Office the text
1345 // object that is put into edit mode would have also to be selected.
1346 // Starting the text edit mode is not enough so we do it here by
1347 // hand.
1348 mbExpectingSelectionChangeEvent = true;
1349 mpView->UnmarkAllObj (pPV);
1350 mpView->MarkObj (mpTextObj, pPV);
1352 if( mpTextObj )
1353 mpTextObj->setActiveText( mnText );
1355 // Turn on the edit mode for the text object.
1356 mpView->SdrBeginTextEdit(mpTextObj, pPV, mpWindow, sal_True, this, pOutlinerView, sal_True, sal_True, bGrabFocus);
1358 SetUpdateMode(sal_True);
1359 mbFoundObject = sal_True;
1366 /*************************************************************************
1368 |* SpellChecker: Error-LinkHdl
1370 \************************************************************************/
1372 IMPL_LINK_INLINE_START( Outliner, SpellError, void *, nLang )
1374 mbError = true;
1375 String aError( SvtLanguageTable::GetLanguageString( (LanguageType)(sal_uLong)nLang ) );
1376 ErrorHandler::HandleError(* new StringErrorInfo(
1377 ERRCODE_SVX_LINGU_LANGUAGENOTEXISTS, aError) );
1378 return 0;
1380 IMPL_LINK_INLINE_END( Outliner, SpellError, void *, nLang )
1385 ESelection Outliner::GetSearchStartPosition (void)
1387 ESelection aPosition;
1388 if (mbDirectionIsForward)
1390 // The default constructor uses the beginning of the text as default.
1391 aPosition = ESelection ();
1393 else
1395 // Retrieve the position after the last character in the last
1396 // paragraph.
1397 sal_uInt16 nParagraphCount = static_cast<sal_uInt16>(GetParagraphCount());
1398 if (nParagraphCount == 0)
1399 aPosition = ESelection();
1400 else
1402 xub_StrLen nLastParagraphLength = GetEditEngine().GetTextLen (
1403 nParagraphCount-1);
1404 aPosition = ESelection (nParagraphCount-1, nLastParagraphLength);
1408 return aPosition;
1414 bool Outliner::HasNoPreviousMatch (void)
1416 OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
1418 DBG_ASSERT (pOutlinerView!=NULL, "outline view in Outliner::HasNoPreviousMatch is NULL");
1420 // Detect whether the cursor stands at the beginning
1421 // resp. at the end of the text.
1422 return pOutlinerView->GetSelection().IsEqual(GetSearchStartPosition ()) == sal_True;
1428 bool Outliner::HandleFailedSearch (void)
1430 bool bContinueSearch = false;
1432 OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
1433 if (pOutlinerView != NULL && mpSearchItem != NULL)
1435 // Detect whether there is/may be a prior match. If there is then
1436 // ask the user whether to wrap arround. Otherwise tell the user
1437 // that there is no match.
1438 if (HasNoPreviousMatch ())
1440 // No match found in the whole presentation. Tell the user.
1441 InfoBox aInfoBox (NULL,
1442 String(SdResId(STR_SAR_NOT_FOUND)));
1443 ShowModalMessageBox (aInfoBox);
1446 else
1448 // No further matches found. Ask the user whether to wrap
1449 // arround and start again.
1450 bContinueSearch = ShowWrapArroundDialog ();
1454 return bContinueSearch;
1458 SdrObject* Outliner::SetObject (
1459 const ::sd::outliner::IteratorPosition& rPosition)
1461 SetViewMode (rPosition.mePageKind);
1462 SetPage (rPosition.meEditMode, (sal_uInt16)rPosition.mnPageIndex);
1463 mnText = rPosition.mnText;
1464 return rPosition.mxObject.get();
1470 void Outliner::SetViewShell (const ::boost::shared_ptr<ViewShell>& rpViewShell)
1472 if (mpViewShell != rpViewShell)
1474 // Set the new view shell.
1475 mpViewShell = rpViewShell;
1476 // When the outline view is not owned by us then we have to clear
1477 // that pointer so that the current one for the new view shell will
1478 // be used (in ProvideOutlinerView).
1479 // if ( ! mbOwnOutlineView)
1480 // mpOutlineView = NULL;
1481 if (mpViewShell.get() != NULL)
1483 mpView = mpViewShell->GetView();
1485 mpWindow = mpViewShell->GetActiveWindow();
1487 mpImpl->ProvideOutlinerView(*this, mpViewShell, mpWindow);
1488 OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
1489 if (pOutlinerView != NULL)
1490 pOutlinerView->SetWindow(mpWindow);
1492 else
1494 mpView = NULL;
1495 mpWindow = NULL;
1503 void Outliner::HandleChangedSelection (void)
1505 maMarkListCopy.clear();
1506 mbRestrictSearchToSelection = (mpView->AreObjectsMarked()==sal_True);
1507 if (mbRestrictSearchToSelection)
1509 // Make a copy of the current mark list.
1510 const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
1511 sal_uLong nCount = rMarkList.GetMarkCount();
1512 if (nCount > 0)
1514 maMarkListCopy.clear();
1515 maMarkListCopy.reserve (nCount);
1516 for (sal_uLong i=0; i<nCount; i++)
1517 maMarkListCopy.push_back (rMarkList.GetMark(i)->GetMarkedSdrObj ());
1519 else
1520 // No marked object. Is this case possible?
1521 mbRestrictSearchToSelection = false;
1529 void Outliner::StartConversion( sal_Int16 nSourceLanguage, sal_Int16 nTargetLanguage,
1530 const Font *pTargetFont, sal_Int32 nOptions, sal_Bool bIsInteractive )
1532 sal_Bool bMultiDoc = mpViewShell->ISA(DrawViewShell);
1534 meMode = TEXT_CONVERSION;
1535 mbDirectionIsForward = true;
1536 mpSearchItem = NULL;
1537 mnConversionLanguage = nSourceLanguage;
1539 BeginConversion();
1541 OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
1542 if (pOutlinerView != NULL)
1544 pOutlinerView->StartTextConversion(
1545 nSourceLanguage,
1546 nTargetLanguage,
1547 pTargetFont,
1548 nOptions,
1549 bIsInteractive,
1550 bMultiDoc);
1553 EndConversion();
1559 /** Prepare to do a text conversion on the current text object. This
1560 includes putting it into edit mode.
1562 void Outliner::PrepareConversion (void)
1564 SetUpdateMode(sal_True);
1565 if( HasConvertibleTextPortion( mnConversionLanguage ) )
1567 SetUpdateMode(sal_False);
1568 mbStringFound = sal_True;
1569 mbMatchMayExist = sal_True;
1571 EnterEditMode ();
1573 mpDrawDocument->GetDocSh()->SetWaitCursor( sal_False );
1574 // Start seach at the right end of the current object's text
1575 // depending on the search direction.
1576 // mpOutlineView->SetSelection (GetSearchStartPosition ());
1578 else
1580 SetUpdateMode(sal_False);
1587 void Outliner::BeginConversion (void)
1589 SetRefDevice( SD_MOD()->GetRefDevice( *mpDrawDocument->GetDocSh() ) );
1591 ViewShellBase* pBase = PTR_CAST(ViewShellBase, SfxViewShell::Current());
1592 if (pBase != NULL)
1593 SetViewShell (pBase->GetMainViewShell());
1595 if (mpViewShell != NULL)
1597 mbStringFound = sal_False;
1599 // Supposed that we are not located at the very beginning/end of the
1600 // document then there may be a match in the document prior/after
1601 // the current position.
1602 mbMatchMayExist = sal_True;
1604 maObjectIterator = ::sd::outliner::Iterator();
1605 maSearchStartPosition = ::sd::outliner::Iterator();
1606 RememberStartPosition();
1608 mpImpl->ProvideOutlinerView(*this, mpViewShell, mpWindow);
1610 HandleChangedSelection ();
1612 ClearModifyFlag();
1618 void Outliner::EndConversion()
1620 EndSpelling();
1626 sal_Bool Outliner::ConvertNextDocument()
1628 if( mpViewShell && mpViewShell->ISA(OutlineViewShell) )
1629 return false;
1631 mpDrawDocument->GetDocSh()->SetWaitCursor( sal_True );
1633 Initialize ( true );
1635 OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
1636 if (pOutlinerView != NULL)
1638 mpWindow = mpViewShell->GetActiveWindow();
1639 pOutlinerView->SetWindow(mpWindow);
1641 ProvideNextTextObject ();
1643 mpDrawDocument->GetDocSh()->SetWaitCursor( sal_False );
1644 ClearModifyFlag();
1646 // for text conversion we automaticly wrap around one
1647 // time and stop at the start shape
1648 if( mpFirstObj )
1650 if( (mnText == 0) && (mpFirstObj == mpObj) )
1651 return false;
1653 else
1655 mpFirstObj = mpObj;
1658 return !mbEndOfSearch;
1664 sal_uInt16 Outliner::ShowModalMessageBox (Dialog& rMessageBox)
1666 // We assume that the parent of the given messge box is NULL, i.e. it is
1667 // modal with respect to the top application window. However, this
1668 // does not affect the search dialog. Therefore we have to lock it here
1669 // while the message box is being shown. We also have to take into
1670 // account that we are called during a spell check and the search dialog
1671 // is not available.
1672 ::Window* pSearchDialog = NULL;
1673 SfxChildWindow* pChildWindow = NULL;
1674 switch (meMode)
1676 case SEARCH:
1677 pChildWindow = SfxViewFrame::Current()->GetChildWindow(
1678 SvxSearchDialogWrapper::GetChildWindowId());
1679 break;
1681 case SPELL:
1682 pChildWindow = SfxViewFrame::Current()->GetChildWindow(
1683 SpellDialogChildWindow::GetChildWindowId());
1684 break;
1686 case TEXT_CONVERSION:
1687 // There should no messages boxes be displayed while doing the
1688 // hangul hanja conversion.
1689 break;
1692 if (pChildWindow != NULL)
1693 pSearchDialog = pChildWindow->GetWindow();
1694 if (pSearchDialog != NULL)
1695 pSearchDialog->EnableInput(sal_False,sal_True);
1697 sal_uInt16 nResult = rMessageBox.Execute();
1699 // Unlock the search dialog.
1700 if (pSearchDialog != NULL)
1701 pSearchDialog->EnableInput(sal_True,sal_True);
1703 return nResult;
1709 //===== Outliner::Implementation ==============================================
1711 Outliner::Implementation::Implementation (void)
1712 : meOriginalEditMode(EM_PAGE),
1713 mbOwnOutlineView(false),
1714 mpOutlineView(NULL)
1721 Outliner::Implementation::~Implementation (void)
1723 if (mbOwnOutlineView && mpOutlineView!=NULL)
1725 mpOutlineView->SetWindow(NULL);
1726 delete mpOutlineView;
1727 mpOutlineView = NULL;
1734 OutlinerView* Outliner::Implementation::GetOutlinerView ()
1736 return mpOutlineView;
1742 /** We try to create a new OutlinerView only when there is none available,
1743 either from an OutlinerViewShell or a previous call to
1744 ProvideOutlinerView(). This is necessary to support the spell checker
1745 which can not cope with exchanging the OutlinerView.
1747 void Outliner::Implementation::ProvideOutlinerView (
1748 Outliner& rOutliner,
1749 const ::boost::shared_ptr<ViewShell>& rpViewShell,
1750 ::Window* pWindow)
1752 if (rpViewShell.get() != NULL)
1754 switch (rpViewShell->GetShellType())
1756 case ViewShell::ST_DRAW:
1757 case ViewShell::ST_IMPRESS:
1758 case ViewShell::ST_NOTES:
1759 case ViewShell::ST_HANDOUT:
1761 // Create a new outline view to do the search on.
1762 bool bInsert = false;
1763 if (mpOutlineView!=NULL && !mbOwnOutlineView)
1764 mpOutlineView = NULL;
1765 if (mpOutlineView == NULL)
1767 mpOutlineView = new OutlinerView(&rOutliner, pWindow);
1768 mbOwnOutlineView = true;
1769 bInsert = true;
1771 else
1772 mpOutlineView->SetWindow(pWindow);
1773 sal_uLong nStat = mpOutlineView->GetControlWord();
1774 nStat &= ~EV_CNTRL_AUTOSCROLL;
1775 mpOutlineView->SetControlWord(nStat);
1776 if (bInsert)
1777 rOutliner.InsertView( mpOutlineView );
1778 rOutliner.SetUpdateMode(sal_False);
1779 mpOutlineView->SetOutputArea (Rectangle (Point(), Size(1, 1)));
1780 rOutliner.SetPaperSize( Size(1, 1) );
1781 rOutliner.SetText( String(), rOutliner.GetParagraph( 0 ) );
1783 meOriginalEditMode =
1784 ::boost::static_pointer_cast<DrawViewShell>(rpViewShell)->GetEditMode();
1786 break;
1788 case ViewShell::ST_OUTLINE:
1790 if (mpOutlineView!=NULL && mbOwnOutlineView)
1791 delete mpOutlineView;
1792 mpOutlineView = rOutliner.GetView(0);
1793 mbOwnOutlineView = false;
1795 break;
1797 default:
1798 case ViewShell::ST_NONE:
1799 case ViewShell::ST_PRESENTATION:
1800 // Ignored
1801 break;
1809 void Outliner::Implementation::ReleaseOutlinerView (void)
1811 if (mbOwnOutlineView)
1813 OutlinerView* pView = mpOutlineView;
1814 mpOutlineView = NULL;
1815 mbOwnOutlineView = false;
1816 if (pView != NULL)
1818 pView->SetWindow(NULL);
1819 delete pView;
1822 else
1824 mpOutlineView = NULL;
1828 } // end of namespace sd