1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "Outliner.hxx"
21 #include <vcl/wrkwin.hxx>
22 #include <vcl/settings.hxx>
24 #include <svl/srchitem.hxx>
25 #include <editeng/colritem.hxx>
26 #include <editeng/eeitem.hxx>
27 #include <editeng/editstat.hxx>
28 #include <vcl/outdev.hxx>
29 #include <svx/dlgutil.hxx>
30 #include <svx/xtable.hxx>
31 #include <vcl/layout.hxx>
32 #include <vcl/msgbox.hxx>
33 #include <sfx2/dispatch.hxx>
34 #include <sfx2/printer.hxx>
35 #include <svx/svxerr.hxx>
36 #include <svx/svdotext.hxx>
37 #include <editeng/unolingu.hxx>
38 #include <svx/svditer.hxx>
39 #include <comphelper/extract.hxx>
40 #include <com/sun/star/linguistic2/XSpellChecker1.hpp>
41 #include <com/sun/star/beans/XPropertySet.hpp>
42 #include <comphelper/processfactory.hxx>
43 #include <editeng/forbiddencharacterstable.hxx>
44 #include <svx/srchdlg.hxx>
45 #include <unotools/linguprops.hxx>
46 #include <unotools/lingucfg.hxx>
47 #include <editeng/editeng.hxx>
48 #include <vcl/metric.hxx>
49 #include <sfx2/viewfrm.hxx>
50 #include <svtools/langtab.hxx>
51 #include <tools/diagnose_ex.h>
53 #include "strings.hrc"
54 #include "sdstring.hrc"
55 #include <editeng/outliner.hxx>
59 #include "sdresid.hxx"
60 #include "DrawViewShell.hxx"
61 #include "OutlineViewShell.hxx"
62 #include "drawdoc.hxx"
63 #include "DrawDocShell.hxx"
64 #include "FrameView.hxx"
65 #include "optsitem.hxx"
66 #include "drawview.hxx"
67 #include "ViewShellBase.hxx"
68 #include "SpellDialogChildWindow.hxx"
69 #include "ToolBarManager.hxx"
70 #include "framework/FrameworkHelper.hxx"
71 #include <svx/svxids.hrc>
72 #include <editeng/editerr.hxx>
73 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
75 using namespace ::com::sun::star
;
76 using namespace ::com::sun::star::uno
;
77 using namespace ::com::sun::star::lang
;
78 using namespace ::com::sun::star::linguistic2
;
80 class SfxStyleSheetPool
;
84 class Outliner::Implementation
87 /** The original edit mode directly after switching to a different view
88 mode. Used for restoring the edit mode when leaving that view mode
91 EditMode meOriginalEditMode
;
96 /** Return the OutlinerView that was provided by the last call to
97 ProvideOutlinerView() (or NULL when there was no such call.)
99 OutlinerView
* GetOutlinerView() { return mpOutlineView
;}
101 /** Provide in the member mpOutlineView an instance of OutlinerView that
102 is either taken from the ViewShell, when it is an OutlineViewShell,
103 or is created. When an OutlinerView already exists it is initialied.
105 void ProvideOutlinerView (
107 const ::boost::shared_ptr
<ViewShell
>& rpViewShell
,
108 vcl::Window
* pWindow
);
110 /** This method is called when the OutlinerView is no longer used.
112 void ReleaseOutlinerView();
115 /** Flag that specifies whether we own the outline view pointed to by
116 <member>mpOutlineView</member> and thus have to
117 delete it in <member>EndSpelling()</member>.
119 bool mbOwnOutlineView
;
121 /** The outline view used for searching and spelling. If searching or
122 spell checking an outline view this data member points to that view.
123 For all other views an instance is created. The
124 <member>mbOwnOutlineView</member> distinguishes between both cases.
126 OutlinerView
* mpOutlineView
;
129 Outliner::Outliner( SdDrawDocument
* pDoc
, sal_uInt16 nMode
)
130 : SdrOutliner( &pDoc
->GetItemPool(), nMode
),
131 mpImpl(new Implementation()),
136 mpDrawDocument(pDoc
),
137 mnConversionLanguage(LANGUAGE_NONE
),
138 mnIgnoreCurrentPageChangesLevel(0),
139 mbStringFound(false),
140 mbMatchMayExist(false),
143 mbEndOfSearch(false),
144 mbFoundObject(false),
146 mbDirectionIsForward(true),
147 mbRestrictSearchToSelection(false),
149 mbProcessCurrentViewOnly(false),
155 meStartViewMode(PK_STANDARD
),
156 meStartEditMode(EM_PAGE
),
157 mnStartPageIndex((sal_uInt16
)-1),
158 mpStartEditedObject(NULL
),
163 maSearchStartPosition(),
164 maLastValidPosition(),
165 mbSelectionHasChanged(false),
166 mbExpectingSelectionChangeEvent(false),
167 mbWholeDocumentProcessed(false),
168 mbPrepareSpellingPending(true)
170 SetStyleSheetPool(static_cast<SfxStyleSheetPool
*>( mpDrawDocument
->GetStyleSheetPool() ));
171 SetEditTextObjectPool( &pDoc
->GetItemPool() );
172 SetCalcFieldValueHdl(LINK(SD_MOD(), SdModule
, CalcFieldValueHdl
));
173 SetForbiddenCharsTable( pDoc
->GetForbiddenCharsTable() );
175 EEControlBits nCntrl
= GetControlWord();
176 nCntrl
|= EEControlBits::ALLOWBIGOBJS
;
177 nCntrl
|= EEControlBits::MARKFIELDS
;
178 nCntrl
|= EEControlBits::AUTOCORRECT
;
180 bool bOnlineSpell
= false;
182 DrawDocShell
* pDocSh
= mpDrawDocument
->GetDocSh();
186 bOnlineSpell
= mpDrawDocument
->GetOnlineSpell();
190 bOnlineSpell
= false;
194 const SvtLinguConfig aLinguConfig
;
197 aAny
= aLinguConfig
.GetProperty( UPN_IS_SPELL_AUTO
);
198 aAny
>>= bOnlineSpell
;
202 OSL_FAIL( "Ill. type in linguistic property" );
207 nCntrl
|= EEControlBits::ONLINESPELLING
;
209 nCntrl
&= ~EEControlBits::ONLINESPELLING
;
211 SetControlWord(nCntrl
);
213 Reference
< XSpellChecker1
> xSpellChecker( LinguMgr::GetSpellChecker() );
214 if ( xSpellChecker
.is() )
215 SetSpeller( xSpellChecker
);
217 Reference
< XHyphenator
> xHyphenator( LinguMgr::GetHyphenator() );
218 if( xHyphenator
.is() )
219 SetHyphenator( xHyphenator
);
221 SetDefaultLanguage( Application::GetSettings().GetLanguageTag().getLanguageType() );
224 /// Nothing spectecular in the destructor.
225 Outliner::~Outliner()
230 /** Prepare find&replace or spellchecking. This distinguishes between three
233 <li>The current shell is a <type>DrawViewShell</type>: Create a
234 <type>OutlinerView</type> object and search all objects of (i) the
235 current mark list, (ii) of the current view, or (iii) of all the view
238 <li>Draw view, slide view</li>
239 <li>Draw view, background view</li>
240 <li>Notes view, slide view</li>
241 <li>Notes view, background view</li>
242 <li>Handout view, slide view</li>
243 <li>Handout view, background view</li>
246 <li>When the current shell is a <type>SdOutlineViewShell</type> then
247 directly operate on it. No switching into other views takes place.</li>
250 void Outliner::PrepareSpelling()
252 mbPrepareSpellingPending
= false;
254 ViewShellBase
* pBase
= PTR_CAST(ViewShellBase
,SfxViewShell::Current());
256 SetViewShell (pBase
->GetMainViewShell());
257 SetRefDevice( SD_MOD()->GetRefDevice( *mpDrawDocument
->GetDocSh() ) );
259 ::boost::shared_ptr
<ViewShell
> pViewShell (mpWeakViewShell
.lock());
262 mbStringFound
= false;
264 mbWholeDocumentProcessed
= false;
265 // Supposed that we are not located at the very beginning/end of
266 // the document then there may be a match in the document
267 // prior/after the current position.
268 mbMatchMayExist
= true;
270 maObjectIterator
= ::sd::outliner::Iterator();
271 maSearchStartPosition
= ::sd::outliner::Iterator();
272 RememberStartPosition();
274 mpImpl
->ProvideOutlinerView(*this, pViewShell
, mpWindow
);
276 HandleChangedSelection ();
281 void Outliner::StartSpelling()
284 mbDirectionIsForward
= true;
288 /** Proxy for method from base class to avoid compiler warning */
289 void Outliner::StartSpelling(EditView
& rView
, unsigned char c
)
291 SdrOutliner::StartSpelling( rView
, c
);
294 /** Free all resources acquired during the search/spell check. After a
295 spell check the start position is restored here.
297 void Outliner::EndSpelling()
299 // Keep old view shell alive until we release the outliner view.
300 ::boost::shared_ptr
<ViewShell
> pViewShell (mpWeakViewShell
.lock());
301 ::boost::shared_ptr
<ViewShell
> pOldViewShell (pViewShell
);
303 ViewShellBase
* pBase
= PTR_CAST(ViewShellBase
,SfxViewShell::Current());
305 pViewShell
= pBase
->GetMainViewShell();
308 mpWeakViewShell
= pViewShell
;
310 // When in <member>PrepareSpelling()</member> a new outline view has
311 // been created then delete it here.
312 bool bViewIsDrawViewShell(pViewShell
&& pViewShell
->ISA(DrawViewShell
));
313 if (bViewIsDrawViewShell
)
315 SetStatusEventHdl(Link
<>());
316 mpView
= pViewShell
->GetView();
317 mpView
->UnmarkAllObj (mpView
->GetSdrPageView());
318 mpView
->SdrEndTextEdit();
319 // Make FuSelection the current function.
320 pViewShell
->GetDispatcher()->Execute(
322 SfxCallMode::SYNCHRON
| SfxCallMode::RECORD
);
324 // Remove and, if previously created by us, delete the outline
326 OutlinerView
* pOutlinerView
= mpImpl
->GetOutlinerView();
327 if (pOutlinerView
!= NULL
)
329 RemoveView(pOutlinerView
);
330 mpImpl
->ReleaseOutlinerView();
336 // Before clearing the modify flag use it as a hint that
337 // changes were done at SpellCheck
340 if(mpView
&& mpView
->ISA(OutlineView
))
341 static_cast<OutlineView
*>(mpView
)->PrepareClose(false);
342 if(mpDrawDocument
&& !mpDrawDocument
->IsChanged())
343 mpDrawDocument
->SetChanged(true);
346 // Now clear the modify flag to have a specified state of
350 // When spell checking then restore the start position.
351 if (meMode
==SPELL
|| meMode
==TEXT_CONVERSION
)
352 RestoreStartPosition ();
354 mpWeakViewShell
.reset();
357 mnStartPageIndex
= (sal_uInt16
) -1;
360 bool Outliner::SpellNextDocument()
362 ::boost::shared_ptr
<ViewShell
> pViewShell (mpWeakViewShell
.lock());
363 if (pViewShell
->ISA(OutlineViewShell
))
365 // When doing a spell check in the outline view then there is
366 // only one document.
367 mbEndOfSearch
= true;
372 if (mpView
->ISA(OutlineView
))
373 static_cast<OutlineView
*>(mpView
)->PrepareClose(false);
374 mpDrawDocument
->GetDocSh()->SetWaitCursor( true );
378 mpWindow
= pViewShell
->GetActiveWindow();
379 OutlinerView
* pOutlinerView
= mpImpl
->GetOutlinerView();
380 if (pOutlinerView
!= NULL
)
381 pOutlinerView
->SetWindow(mpWindow
);
382 ProvideNextTextObject ();
384 mpDrawDocument
->GetDocSh()->SetWaitCursor( false );
388 return !mbEndOfSearch
;
392 * check next text object
394 svx::SpellPortions
Outliner::GetNextSpellSentence()
396 svx::SpellPortions aResult
;
399 // Iterate over sentences and text shapes until a sentence with a
400 // spelling error has been found. If no such sentence can be
401 // found the loop is left through a break.
402 // It is the responsibility of the sd outliner object to correctly
403 // iterate over all text shapes, i.e. switch between views, wrap
404 // around at the end of the document, stop when all text shapes
405 // have been examined exactly once.
406 bool bFoundNextSentence
= false;
407 while ( ! bFoundNextSentence
)
409 OutlinerView
* pOutlinerView
= GetView(0);
410 if (pOutlinerView
!= NULL
)
412 ESelection
aCurrentSelection (pOutlinerView
->GetSelection());
413 if ( ! mbMatchMayExist
414 && maStartSelection
.IsLess(aCurrentSelection
))
417 // Advance to the next sentence.
418 bFoundNextSentence
= SpellSentence (
419 pOutlinerView
->GetEditView(),
423 // When no sentence with spelling errors has been found in the
424 // currently selected text shape or there is no selected text
425 // shape then advance to the next text shape.
426 if ( ! bFoundNextSentence
)
427 if ( ! SpellNextDocument())
428 // All text objects have been processed so exit the
429 // loop and return an empty portions list.
436 /** Go to next match.
438 bool Outliner::StartSearchAndReplace (const SvxSearchItem
* pSearchItem
)
440 bool bEndOfSearch
= true;
442 // clear the search toolbar entry
443 SvxSearchDialogWrapper::SetSearchLabel(SL_Empty
);
445 mpDrawDocument
->GetDocSh()->SetWaitCursor( true );
446 if (mbPrepareSpellingPending
)
448 ViewShellBase
* pBase
= PTR_CAST(ViewShellBase
,SfxViewShell::Current());
449 // Determine whether we have to abort the search. This is necessary
450 // when the main view shell does not support searching.
454 ::boost::shared_ptr
<ViewShell
> pShell (pBase
->GetMainViewShell());
455 SetViewShell(pShell
);
456 if (pShell
.get() == NULL
)
459 switch (pShell
->GetShellType())
461 case ViewShell::ST_DRAW
:
462 case ViewShell::ST_IMPRESS
:
463 case ViewShell::ST_NOTES
:
464 case ViewShell::ST_HANDOUT
:
465 case ViewShell::ST_OUTLINE
:
474 ::boost::shared_ptr
<ViewShell
> pViewShell (mpWeakViewShell
.lock());
477 OSL_ASSERT(pViewShell
);
484 mpSearchItem
= pSearchItem
;
486 mbFoundObject
= false;
488 Initialize ( ! mpSearchItem
->GetBackward());
490 const SvxSearchCmd
nCommand (mpSearchItem
->GetCommand());
491 if (nCommand
== SvxSearchCmd::REPLACE_ALL
)
492 bEndOfSearch
= SearchAndReplaceAll ();
495 RememberStartPosition ();
496 bEndOfSearch
= SearchAndReplaceOnce ();
497 // restore start position if nothing was found
499 RestoreStartPosition ();
500 mnStartPageIndex
= (sal_uInt16
)-1;
503 SfxChildWindow
*pChildWin
=
504 SfxViewFrame::Current()->GetChildWindow(
505 SvxSearchDialogWrapper::GetChildWindowId());
508 SvxSearchDialog
* pSearchDlg
=
509 static_cast<SvxSearchDialog
*>(pChildWin
->GetWindow());
510 pSearchDlg
->SetDocWin( pViewShell
->GetActiveWindow() );
511 pSearchDlg
->SetSrchFlag();
515 mpDrawDocument
->GetDocSh()->SetWaitCursor( false );
520 void Outliner::Initialize (bool bDirectionIsForward
)
522 const bool bIsAtEnd (maObjectIterator
== ::sd::outliner::OutlinerContainer(this).end());
523 const bool bOldDirectionIsForward
= mbDirectionIsForward
;
524 mbDirectionIsForward
= bDirectionIsForward
;
526 if (maObjectIterator
== ::sd::outliner::Iterator())
528 // Initialize a new search.
529 maObjectIterator
= ::sd::outliner::OutlinerContainer(this).current();
530 maCurrentPosition
= *maObjectIterator
;
532 ::boost::shared_ptr
<ViewShell
> pViewShell (mpWeakViewShell
.lock());
535 OSL_ASSERT(pViewShell
);
539 // In case we are searching in an outline view then first remove the
540 // current selection and place cursor at its start or end.
541 if (pViewShell
->ISA(OutlineViewShell
))
543 ESelection aSelection
= mpImpl
->GetOutlinerView()->GetSelection ();
544 if (mbDirectionIsForward
)
546 aSelection
.nEndPara
= aSelection
.nStartPara
;
547 aSelection
.nEndPos
= aSelection
.nStartPos
;
551 aSelection
.nStartPara
= aSelection
.nEndPara
;
552 aSelection
.nStartPos
= aSelection
.nEndPos
;
554 mpImpl
->GetOutlinerView()->SetSelection (aSelection
);
557 // When not beginning the search at the beginning of the search area
558 // then there may be matches before the current position.
559 mbMatchMayExist
= (maObjectIterator
!=::sd::outliner::OutlinerContainer(this).begin());
561 else if (bOldDirectionIsForward
!= mbDirectionIsForward
)
563 // Requested iteration direction has changed. Turn around the iterator.
564 maObjectIterator
.Reverse();
567 // The iterator has pointed to end(), which after the search
568 // direction is reversed, becomes begin().
569 maObjectIterator
= ::sd::outliner::OutlinerContainer(this).begin();
573 // The iterator has pointed to the object one ahead/before the current
574 // one. Now move it to the one before/ahead the current one.
579 mbMatchMayExist
= true;
582 // Initialize the last valid position with where the search starts so
583 // that it always points to a valid position.
584 maLastValidPosition
= *::sd::outliner::OutlinerContainer(this).current();
587 bool Outliner::SearchAndReplaceAll()
589 // Save the current position to be restored after having replaced all
591 RememberStartPosition ();
593 ::boost::shared_ptr
<ViewShell
> pViewShell (mpWeakViewShell
.lock());
596 OSL_ASSERT(pViewShell
);
600 if (pViewShell
->ISA(OutlineViewShell
))
602 // Put the cursor to the beginning/end of the outliner.
603 mpImpl
->GetOutlinerView()->SetSelection (GetSearchStartPosition ());
605 // The outliner does all the work for us when we are in this mode.
606 SearchAndReplaceOnce();
608 else if (pViewShell
->ISA(DrawViewShell
))
610 // Go to beginning/end of document.
611 maObjectIterator
= ::sd::outliner::OutlinerContainer(this).begin();
612 // Switch to the current object only if it is a valid text object.
613 ::sd::outliner::IteratorPosition
aNewPosition (*maObjectIterator
);
614 if (IsValidTextObject (aNewPosition
))
616 maCurrentPosition
= aNewPosition
;
617 SetObject (maCurrentPosition
);
620 // Search/replace until the end of the document is reached.
624 bFoundMatch
= ! SearchAndReplaceOnce();
629 RestoreStartPosition ();
630 mnStartPageIndex
= (sal_uInt16
)-1;
635 bool Outliner::SearchAndReplaceOnce()
639 OutlinerView
* pOutlinerView
= mpImpl
->GetOutlinerView();
640 DBG_ASSERT(pOutlinerView
!=NULL
&& GetEditEngine().HasView( &pOutlinerView
->GetEditView() ),
641 "SearchAndReplace without valid view!" );
643 if( NULL
== pOutlinerView
|| !GetEditEngine().HasView( &pOutlinerView
->GetEditView() ) )
646 ::boost::shared_ptr
<ViewShell
> pViewShell (mpWeakViewShell
.lock());
649 mpView
= pViewShell
->GetView();
650 mpWindow
= pViewShell
->GetActiveWindow();
651 pOutlinerView
->SetWindow(mpWindow
);
653 if (pViewShell
->ISA(DrawViewShell
) )
655 // When replacing we first check if there is a selection
656 // indicating a match. If there is then replace it. The
657 // following call to StartSearchAndReplace will then search for
660 && mpSearchItem
->GetCommand() == SvxSearchCmd::REPLACE
)
661 if (pOutlinerView
->GetSelection().HasRange())
662 pOutlinerView
->StartSearchAndReplace(*mpSearchItem
);
664 // Search for the next match.
665 sal_uLong nMatchCount
= 0;
666 if (mpSearchItem
->GetCommand() != SvxSearchCmd::REPLACE_ALL
)
667 nMatchCount
= pOutlinerView
->StartSearchAndReplace(*mpSearchItem
);
669 // Go to the next text object when there have been no matches in
670 // the current object or the whole object has already been
672 if (nMatchCount
==0 || mpSearchItem
->GetCommand()==SvxSearchCmd::REPLACE_ALL
)
674 ProvideNextTextObject ();
676 if ( ! mbEndOfSearch
)
678 // Remember the current position as the last one with a
680 maLastValidPosition
= maCurrentPosition
;
682 // Now that the mbEndOfSearch flag guards this block the
683 // following assertion and return should not be
684 // necessary anymore.
685 DBG_ASSERT(GetEditEngine().HasView(&pOutlinerView
->GetEditView() ),
686 "SearchAndReplace without valid view!" );
687 if ( ! GetEditEngine().HasView( &pOutlinerView
->GetEditView() ) )
689 mpDrawDocument
->GetDocSh()->SetWaitCursor( false );
693 if (meMode
== SEARCH
)
694 nMatchCount
= pOutlinerView
->StartSearchAndReplace(*mpSearchItem
);
698 else if (pViewShell
->ISA(OutlineViewShell
))
700 mpDrawDocument
->GetDocSh()->SetWaitCursor(false);
701 // The following loop is executed more than once only when a
702 // wrap around search is done.
705 int nResult
= pOutlinerView
->StartSearchAndReplace(*mpSearchItem
);
708 if (HandleFailedSearch ())
710 pOutlinerView
->SetSelection (GetSearchStartPosition ());
715 mbStringFound
= true;
721 mpDrawDocument
->GetDocSh()->SetWaitCursor( false );
723 // notify LibreOfficeKit about changed page
724 if (pViewShell
&& pViewShell
->GetDoc()->isTiledRendering() && mbStringFound
)
726 OString aPayload
= OString::number(maCurrentPosition
.mnPageIndex
);
727 pViewShell
->GetDoc()->libreOfficeKitCallback(LOK_CALLBACK_SET_PART
, aPayload
.getStr());
730 return mbEndOfSearch
;
733 /** Try to detect whether the document or the view (shell) has changed since
734 the last time <member>StartSearchAndReplace()</member> has been called.
736 void Outliner::DetectChange()
738 ::sd::outliner::IteratorPosition
aPosition (maCurrentPosition
);
740 ::boost::shared_ptr
<ViewShell
> pViewShell (mpWeakViewShell
.lock());
741 ::boost::shared_ptr
<DrawViewShell
> pDrawViewShell (
742 ::boost::dynamic_pointer_cast
<DrawViewShell
>(pViewShell
));
744 // Detect whether the view has been switched from the outside.
745 if (pDrawViewShell
.get() != NULL
746 && (aPosition
.meEditMode
!= pDrawViewShell
->GetEditMode()
747 || aPosition
.mePageKind
!= pDrawViewShell
->GetPageKind()))
749 // Either the edit mode or the page kind has changed.
750 SetStatusEventHdl(Link
<>());
752 SdrPageView
* pPageView
= mpView
->GetSdrPageView();
753 if (pPageView
!= NULL
)
754 mpView
->UnmarkAllObj (pPageView
);
755 mpView
->SdrEndTextEdit();
756 SetUpdateMode(false);
757 OutlinerView
* pOutlinerView
= mpImpl
->GetOutlinerView();
758 if (pOutlinerView
!= NULL
)
759 pOutlinerView
->SetOutputArea( Rectangle( Point(), Size(1, 1) ) );
761 SetPaperSize( Size(1, 1) );
762 SetText(OUString(), GetParagraph(0));
764 RememberStartPosition ();
766 mnPageCount
= mpDrawDocument
->GetSdPageCount(pDrawViewShell
->GetPageKind());
767 maObjectIterator
= ::sd::outliner::OutlinerContainer(this).current();
770 // Detect change of the set of selected objects. If their number has
771 // changed start again with the first selected object.
772 else if (DetectSelectionChange())
774 HandleChangedSelection ();
775 maObjectIterator
= ::sd::outliner::OutlinerContainer(this).current();
778 // Detect change of page count. Restart search at first/last page in
780 else if (aPosition
.meEditMode
== EM_PAGE
781 && mpDrawDocument
->GetSdPageCount(aPosition
.mePageKind
) != mnPageCount
)
783 // The number of pages has changed.
784 mnPageCount
= mpDrawDocument
->GetSdPageCount(aPosition
.mePageKind
);
785 maObjectIterator
= ::sd::outliner::OutlinerContainer(this).current();
787 else if (aPosition
.meEditMode
== EM_MASTERPAGE
788 && mpDrawDocument
->GetSdPageCount(aPosition
.mePageKind
) != mnPageCount
)
790 // The number of master pages has changed.
791 mnPageCount
= mpDrawDocument
->GetSdPageCount(aPosition
.mePageKind
);
792 maObjectIterator
= ::sd::outliner::OutlinerContainer(this).current();
796 bool Outliner::DetectSelectionChange()
798 bool bSelectionHasChanged
= false;
800 // If mpObj is NULL then we have not yet found our first match.
801 // Detecting a change makes no sense.
804 const size_t nMarkCount
= mpView
? mpView
->GetMarkedObjectList().GetMarkCount() : 0;
808 // The selection has changed when previously there have been
810 bSelectionHasChanged
= mbRestrictSearchToSelection
;
813 // Check if the only selected object is not the one that we
817 SdrMark
* pMark
= mpView
->GetMarkedObjectList().GetMark(0);
819 bSelectionHasChanged
= (mpObj
!= pMark
->GetMarkedSdrObj ());
823 // We had selected exactly one object.
824 bSelectionHasChanged
= true;
829 return bSelectionHasChanged
;
832 void Outliner::RememberStartPosition()
834 ::boost::shared_ptr
<ViewShell
> pViewShell (mpWeakViewShell
.lock());
837 OSL_ASSERT(pViewShell
);
841 if ( mnStartPageIndex
!= (sal_uInt16
) -1 )
844 if (pViewShell
->ISA(DrawViewShell
))
846 ::boost::shared_ptr
<DrawViewShell
> pDrawViewShell (
847 ::boost::dynamic_pointer_cast
<DrawViewShell
>(pViewShell
));
848 if (pDrawViewShell
.get() != NULL
)
850 meStartViewMode
= pDrawViewShell
->GetPageKind();
851 meStartEditMode
= pDrawViewShell
->GetEditMode();
852 mnStartPageIndex
= pDrawViewShell
->GetCurPageId() - 1;
857 mpStartEditedObject
= mpView
->GetTextEditObject();
858 if (mpStartEditedObject
!= NULL
)
860 // Try to retrieve current caret position only when there is an
862 ::Outliner
* pOutliner
=
863 static_cast<DrawView
*>(mpView
)->GetTextEditOutliner();
864 if (pOutliner
!=NULL
&& pOutliner
->GetViewCount()>0)
866 OutlinerView
* pOutlinerView
= pOutliner
->GetView(0);
867 maStartSelection
= pOutlinerView
->GetSelection();
872 else if (pViewShell
->ISA(OutlineViewShell
))
874 // Remember the current cursor position.
875 OutlinerView
* pView
= GetView(0);
877 pView
->GetSelection();
881 mnStartPageIndex
= (sal_uInt16
)-1;
885 void Outliner::RestoreStartPosition()
887 bool bRestore
= true;
888 // Take a negative start page index as inidicator that restoring the
889 // start position is not requested.
890 if (mnStartPageIndex
== (sal_uInt16
)-1 )
892 // Dont't restore when the view shell is not valid.
893 ::boost::shared_ptr
<ViewShell
> pViewShell (mpWeakViewShell
.lock());
899 if (pViewShell
->ISA(DrawViewShell
))
901 ::boost::shared_ptr
<DrawViewShell
> pDrawViewShell (
902 ::boost::dynamic_pointer_cast
<DrawViewShell
>(pViewShell
));
903 SetViewMode (meStartViewMode
);
904 if (pDrawViewShell
.get() != NULL
)
905 SetPage (meStartEditMode
, mnStartPageIndex
);
907 else if (pViewShell
->ISA(OutlineViewShell
))
909 // Set cursor to its old position.
910 OutlinerView
* pView
= GetView(0);
912 pView
->SetSelection (maStartSelection
);
917 /** The main purpose of this method is to iterate over all shape objects of
918 the search area (current selection, current view, or whole document)
919 until a text object has been found that contains at least one match or
920 until no such object can be found anymore. These two conditions are
921 expressed by setting one of the flags <member>mbFoundObject</member> or
922 <member>mbEndOfSearch</member> to <TRUE/>.
924 void Outliner::ProvideNextTextObject()
926 mbEndOfSearch
= false;
927 mbFoundObject
= false;
929 mpView
->UnmarkAllObj (mpView
->GetSdrPageView());
932 mpView
->SdrEndTextEdit();
934 catch (const ::com::sun::star::uno::Exception
&)
936 DBG_UNHANDLED_EXCEPTION();
938 SetUpdateMode(false);
939 OutlinerView
* pOutlinerView
= mpImpl
->GetOutlinerView();
940 if (pOutlinerView
!= NULL
)
941 pOutlinerView
->SetOutputArea( Rectangle( Point(), Size(1, 1) ) );
943 SetPaperSize( Size(1, 1) );
944 SetText(OUString(), GetParagraph(0));
948 // Iterate until a valid text object has been found or the search ends.
954 if (maObjectIterator
!= ::sd::outliner::OutlinerContainer(this).end())
956 maCurrentPosition
= *maObjectIterator
;
957 // Switch to the current object only if it is a valid text object.
958 if (IsValidTextObject (maCurrentPosition
))
960 mpObj
= SetObject (maCurrentPosition
);
966 PutTextIntoOutliner ();
968 ::boost::shared_ptr
<ViewShell
> pViewShell (mpWeakViewShell
.lock());
973 PrepareSearchAndReplace ();
976 PrepareSpellCheck ();
978 case TEXT_CONVERSION
:
986 mbEndOfSearch
= true;
990 while ( ! (mbFoundObject
|| mbEndOfSearch
));
993 void Outliner::EndOfSearch()
995 ::boost::shared_ptr
<ViewShell
> pViewShell (mpWeakViewShell
.lock());
998 OSL_ASSERT(pViewShell
);
1002 // Before we display a dialog we first jump to where the last valid text
1003 // object was found. All page and view mode switching since then was
1004 // temporary and should not be visible to the user.
1005 if ( ! pViewShell
->ISA(OutlineViewShell
))
1006 SetObject (maLastValidPosition
);
1008 if (mbRestrictSearchToSelection
)
1009 ShowEndOfSearchDialog ();
1012 // When no match has been found so far then terminate the search.
1013 if ( ! mbMatchMayExist
)
1015 ShowEndOfSearchDialog ();
1016 mbEndOfSearch
= true;
1018 // Ask the user whether to wrap around and continue the search or
1020 else if (meMode
==TEXT_CONVERSION
|| ShowWrapArroundDialog ())
1022 mbMatchMayExist
= false;
1023 // Everything back to beginning (or end?) of the document.
1024 maObjectIterator
= ::sd::outliner::OutlinerContainer(this).begin();
1025 if (pViewShell
->ISA(OutlineViewShell
))
1027 // Set cursor to first character of the document.
1028 OutlinerView
* pOutlinerView
= mpImpl
->GetOutlinerView();
1029 if (pOutlinerView
!= NULL
)
1030 pOutlinerView
->SetSelection (GetSearchStartPosition ());
1033 mbEndOfSearch
= false;
1038 mbEndOfSearch
= true;
1043 void Outliner::ShowEndOfSearchDialog()
1045 mbWholeDocumentProcessed
= true;
1047 if (meMode
== SEARCH
)
1051 SvxSearchDialogWrapper::SetSearchLabel(SL_NotFound
);
1052 mpDrawDocument
->libreOfficeKitCallback(LOK_CALLBACK_SEARCH_NOT_FOUND
,
1053 mpSearchItem
->GetSearchString().toUtf8().getStr());
1056 // don't do anything else for search
1061 if (mpView
->AreObjectsMarked())
1062 aString
= SD_RESSTR(STR_END_SPELLING_OBJ
);
1064 aString
= SD_RESSTR(STR_END_SPELLING
);
1066 // Show the message in an info box that is modal with respect to the
1067 // whole application.
1068 ScopedVclPtrInstance
< MessageDialog
> aInfoBox(nullptr, aString
, VCL_MESSAGE_INFO
);
1069 ShowModalMessageBox (*aInfoBox
.get());
1072 bool Outliner::ShowWrapArroundDialog()
1074 // Determine whether to show the dialog.
1077 // When searching display the dialog only for single find&replace.
1078 const SvxSearchCmd
nCommand(mpSearchItem
->GetCommand());
1079 if (nCommand
== SvxSearchCmd::REPLACE
|| nCommand
== SvxSearchCmd::FIND
)
1081 if (mbDirectionIsForward
)
1082 SvxSearchDialogWrapper::SetSearchLabel(SL_End
);
1084 SvxSearchDialogWrapper::SetSearchLabel(SL_Start
);
1092 // show dialog only for spelling
1093 if (meMode
!= SPELL
)
1096 // The question text depends on the search direction.
1097 bool bImpress
= mpDrawDocument
&& mpDrawDocument
->GetDocumentType() == DOCUMENT_TYPE_IMPRESS
;
1099 sal_uInt16 nStringId
;
1100 if (mbDirectionIsForward
)
1101 nStringId
= bImpress
? STR_SAR_WRAP_FORWARD
: STR_SAR_WRAP_FORWARD_DRAW
;
1103 nStringId
= bImpress
? STR_SAR_WRAP_BACKWARD
: STR_SAR_WRAP_BACKWARD_DRAW
;
1105 // Pop up question box that asks the user whether to wrap around.
1106 // The dialog is made modal with respect to the whole application.
1107 ScopedVclPtrInstance
<QueryBox
> aQuestionBox(nullptr, WB_YES_NO
| WB_DEF_YES
, SD_RESSTR(nStringId
));
1108 aQuestionBox
->SetImage(QueryBox::GetStandardImage());
1109 sal_uInt16 nBoxResult
= ShowModalMessageBox(*aQuestionBox
.get());
1111 return (nBoxResult
== RET_YES
);
1114 bool Outliner::IsValidTextObject (const ::sd::outliner::IteratorPosition
& rPosition
)
1116 SdrTextObj
* pObject
= dynamic_cast< SdrTextObj
* >( rPosition
.mxObject
.get() );
1117 return (pObject
!= NULL
) && pObject
->HasText() && ! pObject
->IsEmptyPresObj();
1120 void Outliner::PutTextIntoOutliner()
1122 mpTextObj
= dynamic_cast<SdrTextObj
*>( mpObj
);
1123 if ( mpTextObj
&& mpTextObj
->HasText() && !mpTextObj
->IsEmptyPresObj() )
1125 SdrText
* pText
= mpTextObj
->getText( mnText
);
1126 mpParaObj
= pText
? pText
->GetOutlinerParaObject() : NULL
;
1128 if (mpParaObj
!= NULL
)
1130 SetText(*mpParaObj
);
1141 void Outliner::PrepareSpellCheck()
1143 EESpellState eState
= HasSpellErrors();
1144 DBG_ASSERT(eState
!= EE_SPELL_NOSPELLER
, "No SpellChecker");
1146 if (eState
== EE_SPELL_NOLANGUAGE
)
1149 mbEndOfSearch
= true;
1150 ScopedVclPtrInstance
<MessageDialog
> aErrorBox (
1151 nullptr, SD_RESSTR(STR_NOLANGUAGE
));
1152 ShowModalMessageBox (*aErrorBox
.get());
1154 else if (eState
!= EE_SPELL_OK
)
1156 // When spell checking we have to test whether we have processed the
1157 // whole document and have reached the start page again.
1158 if (meMode
== SPELL
)
1160 if (maSearchStartPosition
== ::sd::outliner::Iterator())
1161 // Remember the position of the first text object so that we
1162 // know when we have processed the whole document.
1163 maSearchStartPosition
= maObjectIterator
;
1164 else if (maSearchStartPosition
== maObjectIterator
)
1166 mbEndOfSearch
= true;
1170 EnterEditMode( false );
1174 void Outliner::PrepareSearchAndReplace()
1176 if (HasText( *mpSearchItem
))
1178 mbStringFound
= true;
1179 mbMatchMayExist
= true;
1181 EnterEditMode(false);
1183 mpDrawDocument
->GetDocSh()->SetWaitCursor( false );
1184 // Start search at the right end of the current object's text
1185 // depending on the search direction.
1186 OutlinerView
* pOutlinerView
= mpImpl
->GetOutlinerView();
1187 if (pOutlinerView
!= NULL
)
1188 pOutlinerView
->SetSelection (GetSearchStartPosition ());
1192 void Outliner::SetViewMode (PageKind ePageKind
)
1194 ::boost::shared_ptr
<ViewShell
> pViewShell (mpWeakViewShell
.lock());
1195 ::boost::shared_ptr
<DrawViewShell
> pDrawViewShell(
1196 ::boost::dynamic_pointer_cast
<DrawViewShell
>(pViewShell
));
1197 if (pDrawViewShell
.get()!=NULL
&& ePageKind
!= pDrawViewShell
->GetPageKind())
1199 // Restore old edit mode.
1200 pDrawViewShell
->ChangeEditMode(mpImpl
->meOriginalEditMode
, false);
1202 SetStatusEventHdl(Link
<>());
1208 sViewURL
= framework::FrameworkHelper::msImpressViewURL
;
1211 sViewURL
= framework::FrameworkHelper::msNotesViewURL
;
1214 sViewURL
= framework::FrameworkHelper::msHandoutViewURL
;
1217 // The text object iterator is destroyed when the shells are
1218 // switched but we need it so save it and restore it afterwards.
1219 ::sd::outliner::Iterator
aIterator (maObjectIterator
);
1220 bool bMatchMayExist
= mbMatchMayExist
;
1222 ViewShellBase
& rBase
= pViewShell
->GetViewShellBase();
1223 SetViewShell(::boost::shared_ptr
<ViewShell
>());
1224 framework::FrameworkHelper::Instance(rBase
)->RequestView(
1226 framework::FrameworkHelper::msCenterPaneURL
);
1228 // Force (well, request) a synchronous update of the configuration.
1229 // In a better world we would handle the asynchronous view update
1230 // instead. But that would involve major restucturing of the
1232 framework::FrameworkHelper::Instance(rBase
)->RequestSynchronousUpdate();
1233 SetViewShell(rBase
.GetMainViewShell());
1235 // Switching to another view shell has intermediatly called
1236 // EndSpelling(). A PrepareSpelling() is pending, so call that now.
1239 // Update the number of pages so that
1240 // <member>DetectChange()</member> has the correct value to compare
1242 mnPageCount
= mpDrawDocument
->GetSdPageCount(ePageKind
);
1244 maObjectIterator
= aIterator
;
1245 mbMatchMayExist
= bMatchMayExist
;
1247 // Save edit mode so that it can be restored when switching the view
1249 pDrawViewShell
= ::boost::dynamic_pointer_cast
<DrawViewShell
>(pViewShell
);
1250 OSL_ASSERT(pDrawViewShell
.get()!=NULL
);
1251 if (pDrawViewShell
.get() != NULL
)
1252 mpImpl
->meOriginalEditMode
= pDrawViewShell
->GetEditMode();
1256 void Outliner::SetPage (EditMode eEditMode
, sal_uInt16 nPageIndex
)
1258 if ( ! mbRestrictSearchToSelection
)
1260 ::boost::shared_ptr
<ViewShell
> pViewShell (mpWeakViewShell
.lock());
1261 ::boost::shared_ptr
<DrawViewShell
> pDrawViewShell(
1262 ::boost::dynamic_pointer_cast
<DrawViewShell
>(pViewShell
));
1263 OSL_ASSERT(pDrawViewShell
.get()!=NULL
);
1264 if (pDrawViewShell
.get() != NULL
)
1266 pDrawViewShell
->ChangeEditMode(eEditMode
, false);
1267 pDrawViewShell
->SwitchPage(nPageIndex
);
1272 void Outliner::EnterEditMode (bool bGrabFocus
)
1274 OutlinerView
* pOutlinerView
= mpImpl
->GetOutlinerView();
1275 if (pOutlinerView
&& mpTextObj
)
1277 pOutlinerView
->SetOutputArea( Rectangle( Point(), Size(1, 1)));
1278 SetPaperSize( mpTextObj
->GetLogicRect().GetSize() );
1279 SdrPageView
* pPV
= mpView
->GetSdrPageView();
1281 // Make FuText the current function.
1282 SfxUInt16Item
aItem (SID_TEXTEDIT
, 1);
1283 ::boost::shared_ptr
<ViewShell
> pViewShell (mpWeakViewShell
.lock());
1284 pViewShell
->GetDispatcher()->
1285 Execute(SID_TEXTEDIT
, SfxCallMode::SYNCHRON
|
1286 SfxCallMode::RECORD
, &aItem
, 0L);
1288 // To be consistent with the usual behaviour in the Office the text
1289 // object that is put into edit mode would have also to be selected.
1290 // Starting the text edit mode is not enough so we do it here by
1292 mbExpectingSelectionChangeEvent
= true;
1293 mpView
->UnmarkAllObj (pPV
);
1294 mpView
->MarkObj (mpTextObj
, pPV
);
1296 mpTextObj
->setActiveText( mnText
);
1298 // Turn on the edit mode for the text object.
1299 mpView
->SdrBeginTextEdit(mpTextObj
, pPV
, mpWindow
, true, this, pOutlinerView
, true, true, bGrabFocus
);
1301 SetUpdateMode(true);
1302 mbFoundObject
= true;
1307 * SpellChecker: Error link handler
1309 IMPL_LINK( Outliner
, SpellError
, void *, nLang
)
1312 OUString
aError( SvtLanguageTable::GetLanguageString( (LanguageType
)reinterpret_cast<sal_uLong
>(nLang
) ) );
1313 ErrorHandler::HandleError(* new StringErrorInfo(
1314 ERRCODE_SVX_LINGU_LANGUAGENOTEXISTS
, aError
) );
1318 ESelection
Outliner::GetSearchStartPosition()
1320 ESelection aPosition
;
1321 if (mbDirectionIsForward
)
1323 // The default constructor uses the beginning of the text as default.
1324 aPosition
= ESelection ();
1328 // Retrieve the position after the last character in the last
1330 sal_Int32 nParagraphCount
= GetParagraphCount();
1331 if (nParagraphCount
== 0)
1332 aPosition
= ESelection();
1335 sal_Int32 nLastParagraphLength
= GetEditEngine().GetTextLen (
1337 aPosition
= ESelection (nParagraphCount
-1, nLastParagraphLength
);
1344 bool Outliner::HasNoPreviousMatch()
1346 OutlinerView
* pOutlinerView
= mpImpl
->GetOutlinerView();
1348 DBG_ASSERT (pOutlinerView
!=NULL
, "outline view in Outliner::HasNoPreviousMatch is NULL");
1350 // Detect whether the cursor stands at the beginning
1351 // resp. at the end of the text.
1352 return pOutlinerView
->GetSelection().IsEqual(GetSearchStartPosition ());
1355 bool Outliner::HandleFailedSearch()
1357 bool bContinueSearch
= false;
1359 OutlinerView
* pOutlinerView
= mpImpl
->GetOutlinerView();
1360 if (pOutlinerView
!= NULL
&& mpSearchItem
!= NULL
)
1362 // Detect whether there is/may be a prior match. If there is then
1363 // ask the user whether to wrap around. Otherwise tell the user
1364 // that there is no match.
1365 if (HasNoPreviousMatch ())
1367 // No match found in the whole presentation.
1368 SvxSearchDialogWrapper::SetSearchLabel(SL_NotFound
);
1373 // No further matches found. Ask the user whether to wrap
1374 // around and start again.
1375 bContinueSearch
= ShowWrapArroundDialog();
1379 return bContinueSearch
;
1382 SdrObject
* Outliner::SetObject (
1383 const ::sd::outliner::IteratorPosition
& rPosition
)
1385 SetViewMode (rPosition
.mePageKind
);
1386 SetPage (rPosition
.meEditMode
, (sal_uInt16
)rPosition
.mnPageIndex
);
1387 mnText
= rPosition
.mnText
;
1388 return rPosition
.mxObject
.get();
1391 void Outliner::SetViewShell (const ::boost::shared_ptr
<ViewShell
>& rpViewShell
)
1393 ::boost::shared_ptr
<ViewShell
> pViewShell (mpWeakViewShell
.lock());
1394 if (pViewShell
!= rpViewShell
)
1396 // Set the new view shell.
1397 mpWeakViewShell
= rpViewShell
;
1398 // When the outline view is not owned by us then we have to clear
1399 // that pointer so that the current one for the new view shell will
1400 // be used (in ProvideOutlinerView).
1403 mpView
= rpViewShell
->GetView();
1405 mpWindow
= rpViewShell
->GetActiveWindow();
1407 mpImpl
->ProvideOutlinerView(*this, rpViewShell
, mpWindow
);
1408 OutlinerView
* pOutlinerView
= mpImpl
->GetOutlinerView();
1409 if (pOutlinerView
!= NULL
)
1410 pOutlinerView
->SetWindow(mpWindow
);
1420 void Outliner::HandleChangedSelection()
1422 maMarkListCopy
.clear();
1423 mbRestrictSearchToSelection
= mpView
->AreObjectsMarked();
1424 if (mbRestrictSearchToSelection
)
1426 // Make a copy of the current mark list.
1427 const SdrMarkList
& rMarkList
= mpView
->GetMarkedObjectList();
1428 const size_t nCount
= rMarkList
.GetMarkCount();
1431 maMarkListCopy
.clear();
1432 maMarkListCopy
.reserve (nCount
);
1433 for (size_t i
=0; i
<nCount
; ++i
)
1434 maMarkListCopy
.push_back (rMarkList
.GetMark(i
)->GetMarkedSdrObj ());
1437 // No marked object. Is this case possible?
1438 mbRestrictSearchToSelection
= false;
1442 void Outliner::StartConversion( sal_Int16 nSourceLanguage
, sal_Int16 nTargetLanguage
,
1443 const vcl::Font
*pTargetFont
, sal_Int32 nOptions
, bool bIsInteractive
)
1445 ::boost::shared_ptr
<ViewShell
> pViewShell (mpWeakViewShell
.lock());
1446 bool bMultiDoc
= pViewShell
->ISA(DrawViewShell
);
1448 meMode
= TEXT_CONVERSION
;
1449 mbDirectionIsForward
= true;
1450 mpSearchItem
= NULL
;
1451 mnConversionLanguage
= nSourceLanguage
;
1455 OutlinerView
* pOutlinerView
= mpImpl
->GetOutlinerView();
1456 if (pOutlinerView
!= NULL
)
1458 pOutlinerView
->StartTextConversion(
1470 /** Prepare to do a text conversion on the current text object. This
1471 includes putting it into edit mode.
1473 void Outliner::PrepareConversion()
1475 SetUpdateMode(true);
1476 if( HasConvertibleTextPortion( mnConversionLanguage
) )
1478 SetUpdateMode(false);
1479 mbStringFound
= true;
1480 mbMatchMayExist
= true;
1484 mpDrawDocument
->GetDocSh()->SetWaitCursor( false );
1485 // Start search at the right end of the current object's text
1486 // depending on the search direction.
1490 SetUpdateMode(false);
1494 void Outliner::BeginConversion()
1496 SetRefDevice( SD_MOD()->GetRefDevice( *mpDrawDocument
->GetDocSh() ) );
1498 ViewShellBase
* pBase
= PTR_CAST(ViewShellBase
, SfxViewShell::Current());
1500 SetViewShell (pBase
->GetMainViewShell());
1502 ::boost::shared_ptr
<ViewShell
> pViewShell (mpWeakViewShell
.lock());
1505 mbStringFound
= false;
1507 // Supposed that we are not located at the very beginning/end of the
1508 // document then there may be a match in the document prior/after
1509 // the current position.
1510 mbMatchMayExist
= true;
1512 maObjectIterator
= ::sd::outliner::Iterator();
1513 maSearchStartPosition
= ::sd::outliner::Iterator();
1514 RememberStartPosition();
1516 mpImpl
->ProvideOutlinerView(*this, pViewShell
, mpWindow
);
1518 HandleChangedSelection ();
1523 void Outliner::EndConversion()
1528 bool Outliner::ConvertNextDocument()
1530 ::boost::shared_ptr
<ViewShell
> pViewShell (mpWeakViewShell
.lock());
1531 if (pViewShell
&& pViewShell
->ISA(OutlineViewShell
) )
1534 mpDrawDocument
->GetDocSh()->SetWaitCursor( true );
1536 Initialize ( true );
1538 OutlinerView
* pOutlinerView
= mpImpl
->GetOutlinerView();
1539 if (pOutlinerView
!= NULL
)
1541 mpWindow
= pViewShell
->GetActiveWindow();
1542 pOutlinerView
->SetWindow(mpWindow
);
1544 ProvideNextTextObject ();
1546 mpDrawDocument
->GetDocSh()->SetWaitCursor( false );
1549 // for text conversion we automatically wrap around one
1550 // time and stop at the start shape
1553 if( (mnText
== 0) && (mpFirstObj
== mpObj
) )
1561 return !mbEndOfSearch
;
1564 sal_uInt16
Outliner::ShowModalMessageBox (Dialog
& rMessageBox
)
1566 // We assume that the parent of the given messge box is NULL, i.e. it is
1567 // modal with respect to the top application window. However, this
1568 // does not affect the search dialog. Therefore we have to lock it here
1569 // while the message box is being shown. We also have to take into
1570 // account that we are called during a spell check and the search dialog
1571 // is not available.
1572 vcl::Window
* pSearchDialog
= NULL
;
1573 SfxChildWindow
* pChildWindow
= NULL
;
1577 pChildWindow
= SfxViewFrame::Current()->GetChildWindow(
1578 SvxSearchDialogWrapper::GetChildWindowId());
1582 pChildWindow
= SfxViewFrame::Current()->GetChildWindow(
1583 SpellDialogChildWindow::GetChildWindowId());
1586 case TEXT_CONVERSION
:
1587 // There should no messages boxes be displayed while doing the
1588 // hangul hanja conversion.
1592 if (pChildWindow
!= NULL
)
1593 pSearchDialog
= pChildWindow
->GetWindow();
1594 if (pSearchDialog
!= NULL
)
1595 pSearchDialog
->EnableInput(false,true);
1597 sal_uInt16 nResult
= rMessageBox
.Execute();
1599 // Unlock the search dialog.
1600 if (pSearchDialog
!= NULL
)
1601 pSearchDialog
->EnableInput(true,true);
1606 //===== Outliner::Implementation ==============================================
1608 Outliner::Implementation::Implementation()
1609 : meOriginalEditMode(EM_PAGE
),
1610 mbOwnOutlineView(false),
1615 Outliner::Implementation::~Implementation()
1617 if (mbOwnOutlineView
&& mpOutlineView
!=NULL
)
1619 mpOutlineView
->SetWindow(NULL
);
1620 delete mpOutlineView
;
1621 mpOutlineView
= NULL
;
1625 /** We try to create a new OutlinerView only when there is none available,
1626 either from an OutlinerViewShell or a previous call to
1627 ProvideOutlinerView(). This is necessary to support the spell checker
1628 which can not cope with exchanging the OutlinerView.
1630 void Outliner::Implementation::ProvideOutlinerView (
1631 Outliner
& rOutliner
,
1632 const ::boost::shared_ptr
<ViewShell
>& rpViewShell
,
1633 vcl::Window
* pWindow
)
1635 if (rpViewShell
.get() != NULL
)
1637 switch (rpViewShell
->GetShellType())
1639 case ViewShell::ST_DRAW
:
1640 case ViewShell::ST_IMPRESS
:
1641 case ViewShell::ST_NOTES
:
1642 case ViewShell::ST_HANDOUT
:
1644 // Create a new outline view to do the search on.
1645 bool bInsert
= false;
1646 if (mpOutlineView
!=NULL
&& !mbOwnOutlineView
)
1647 mpOutlineView
= NULL
;
1648 if (mpOutlineView
== NULL
)
1650 mpOutlineView
= new OutlinerView(&rOutliner
, pWindow
);
1651 mbOwnOutlineView
= true;
1655 mpOutlineView
->SetWindow(pWindow
);
1656 EVControlBits nStat
= mpOutlineView
->GetControlWord();
1657 nStat
&= ~EVControlBits::AUTOSCROLL
;
1658 mpOutlineView
->SetControlWord(nStat
);
1660 rOutliner
.InsertView( mpOutlineView
);
1661 rOutliner
.SetUpdateMode(false);
1662 mpOutlineView
->SetOutputArea (Rectangle (Point(), Size(1, 1)));
1663 rOutliner
.SetPaperSize( Size(1, 1) );
1664 rOutliner
.SetText(OUString(), rOutliner
.GetParagraph(0));
1666 meOriginalEditMode
=
1667 ::boost::static_pointer_cast
<DrawViewShell
>(rpViewShell
)->GetEditMode();
1671 case ViewShell::ST_OUTLINE
:
1673 if (mpOutlineView
!=NULL
&& mbOwnOutlineView
)
1674 delete mpOutlineView
;
1675 mpOutlineView
= rOutliner
.GetView(0);
1676 mbOwnOutlineView
= false;
1681 case ViewShell::ST_NONE
:
1682 case ViewShell::ST_PRESENTATION
:
1689 void Outliner::Implementation::ReleaseOutlinerView()
1691 if (mbOwnOutlineView
)
1693 OutlinerView
* pView
= mpOutlineView
;
1694 mpOutlineView
= NULL
;
1695 mbOwnOutlineView
= false;
1698 pView
->SetWindow(NULL
);
1704 mpOutlineView
= NULL
;
1708 } // end of namespace sd
1710 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */