xref: /trunk/main/sd/source/ui/view/Outliner.cxx (revision 60b45af21af5e203a98ac17744d87e809553f85b)
1cdf0e10cSrcweir /*************************************************************************
2cdf0e10cSrcweir  *
3cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4cdf0e10cSrcweir  *
5cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6cdf0e10cSrcweir  *
7cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8cdf0e10cSrcweir  *
9cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10cdf0e10cSrcweir  *
11cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14cdf0e10cSrcweir  *
15cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20cdf0e10cSrcweir  *
21cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25cdf0e10cSrcweir  *
26cdf0e10cSrcweir  ************************************************************************/
27cdf0e10cSrcweir 
28cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29cdf0e10cSrcweir #include "precompiled_sd.hxx"
30cdf0e10cSrcweir 
31cdf0e10cSrcweir #include "Outliner.hxx"
32cdf0e10cSrcweir #include <vcl/wrkwin.hxx>
33cdf0e10cSrcweir #include <svl/srchitem.hxx>
34cdf0e10cSrcweir #include <editeng/colritem.hxx>
35cdf0e10cSrcweir #include <editeng/eeitem.hxx>
36cdf0e10cSrcweir #include <editeng/editstat.hxx>
37cdf0e10cSrcweir #include <vcl/outdev.hxx>
38cdf0e10cSrcweir #include <svx/dlgutil.hxx>
39cdf0e10cSrcweir #include <svx/xtable.hxx>
40cdf0e10cSrcweir #include <vcl/msgbox.hxx>
41cdf0e10cSrcweir #include <sfx2/dispatch.hxx>
42cdf0e10cSrcweir #include <sfx2/printer.hxx>
43cdf0e10cSrcweir #include <svx/svxerr.hxx>
44cdf0e10cSrcweir #include <svx/svdotext.hxx>
45cdf0e10cSrcweir #include <editeng/unolingu.hxx>
46cdf0e10cSrcweir #include <svx/svditer.hxx>
47cdf0e10cSrcweir #include <comphelper/extract.hxx>
48cdf0e10cSrcweir #include <com/sun/star/linguistic2/XSpellChecker1.hpp>
49cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp>
50cdf0e10cSrcweir #include <comphelper/processfactory.hxx>
51cdf0e10cSrcweir #include <editeng/eeitem.hxx>
52cdf0e10cSrcweir #include <editeng/forbiddencharacterstable.hxx>
53cdf0e10cSrcweir #include <svx/srchdlg.hxx>
54cdf0e10cSrcweir #include <unotools/linguprops.hxx>
55cdf0e10cSrcweir #include <unotools/lingucfg.hxx>
56cdf0e10cSrcweir #include <editeng/editeng.hxx>
57cdf0e10cSrcweir #include <vcl/metric.hxx>
58cdf0e10cSrcweir #include <sfx2/viewfrm.hxx>
59cdf0e10cSrcweir #include <svtools/langtab.hxx>
60cdf0e10cSrcweir #include <tools/diagnose_ex.h>
61cdf0e10cSrcweir 
62cdf0e10cSrcweir #include "strings.hrc"
63cdf0e10cSrcweir #include "sdstring.hrc"
64cdf0e10cSrcweir #include "eetext.hxx"
65cdf0e10cSrcweir #include "sdpage.hxx"
66cdf0e10cSrcweir #include "app.hxx"
67cdf0e10cSrcweir #include "Window.hxx"
68cdf0e10cSrcweir #include "sdresid.hxx"
69cdf0e10cSrcweir #include "DrawViewShell.hxx"
70cdf0e10cSrcweir #include "OutlineViewShell.hxx"
71cdf0e10cSrcweir #include "drawdoc.hxx"
72cdf0e10cSrcweir #include "DrawDocShell.hxx"
73cdf0e10cSrcweir #include "FrameView.hxx"
74cdf0e10cSrcweir #include "optsitem.hxx"
75cdf0e10cSrcweir #include "drawview.hxx"
76cdf0e10cSrcweir #include "ViewShellBase.hxx"
77cdf0e10cSrcweir #include "SpellDialogChildWindow.hxx"
78cdf0e10cSrcweir #include "ToolBarManager.hxx"
79cdf0e10cSrcweir #include "framework/FrameworkHelper.hxx"
80cdf0e10cSrcweir #include <svx/svxids.hrc>
81cdf0e10cSrcweir #include <editeng/editerr.hxx>
82cdf0e10cSrcweir 
83cdf0e10cSrcweir using ::rtl::OUString;
84cdf0e10cSrcweir using namespace ::com::sun::star;
85cdf0e10cSrcweir using namespace ::com::sun::star::uno;
86cdf0e10cSrcweir using namespace ::com::sun::star::lang;
87cdf0e10cSrcweir using namespace ::com::sun::star::linguistic2;
88cdf0e10cSrcweir 
89cdf0e10cSrcweir class SfxStyleSheetPool;
90cdf0e10cSrcweir 
91cdf0e10cSrcweir namespace sd {
92cdf0e10cSrcweir 
93cdf0e10cSrcweir class Outliner::Implementation
94cdf0e10cSrcweir {
95cdf0e10cSrcweir public:
96cdf0e10cSrcweir     /** The original edit mode directly after switching to a different view
97cdf0e10cSrcweir         mode.  Used for restoring the edit mode when leaving that view mode
98cdf0e10cSrcweir         again.
99cdf0e10cSrcweir     */
100cdf0e10cSrcweir     EditMode meOriginalEditMode;
101cdf0e10cSrcweir 
102cdf0e10cSrcweir     Implementation (void);
103cdf0e10cSrcweir     ~Implementation (void);
104cdf0e10cSrcweir 
105cdf0e10cSrcweir     /** Return the OutlinerView that was provided by the last call to
106cdf0e10cSrcweir         ProvideOutlinerView() (or NULL when there was no such call.)
107cdf0e10cSrcweir     */
108cdf0e10cSrcweir     OutlinerView* GetOutlinerView (void);
109cdf0e10cSrcweir 
110cdf0e10cSrcweir     /** Provide in the member mpOutlineView an instance of OutlinerView that
111cdf0e10cSrcweir         is either taken from the ViewShell, when it is an OutlineViewShell,
112cdf0e10cSrcweir         or is created.  When an OutlinerView already exists it is initialied.
113cdf0e10cSrcweir     */
114cdf0e10cSrcweir     void ProvideOutlinerView (
115cdf0e10cSrcweir         Outliner& rOutliner,
116cdf0e10cSrcweir         const ::boost::shared_ptr<ViewShell>& rpViewShell,
117cdf0e10cSrcweir         ::Window* pWindow);
118cdf0e10cSrcweir 
119cdf0e10cSrcweir     /** This method is called when the OutlinerView is no longer used.
120cdf0e10cSrcweir     */
121cdf0e10cSrcweir     void ReleaseOutlinerView (void);
122cdf0e10cSrcweir 
123cdf0e10cSrcweir private:
124cdf0e10cSrcweir     /** Flag that specifies whether we own the outline view pointed to by
125cdf0e10cSrcweir         <member>mpOutlineView</member> and thus have to
126cdf0e10cSrcweir         delete it in <member>EndSpelling()</member>.
127cdf0e10cSrcweir     */
128cdf0e10cSrcweir     bool mbOwnOutlineView;
129cdf0e10cSrcweir 
130cdf0e10cSrcweir     /** The outline view used for searching and spelling.  If searching or
131cdf0e10cSrcweir         spell checking an outline view this data member points to that view.
132cdf0e10cSrcweir         For all other views an instance is created.  The
133cdf0e10cSrcweir         <member>mbOwnOutlineView</member> distinguishes between both cases.
134cdf0e10cSrcweir     */
135cdf0e10cSrcweir     OutlinerView* mpOutlineView;
136cdf0e10cSrcweir };
137cdf0e10cSrcweir 
138cdf0e10cSrcweir 
139cdf0e10cSrcweir 
140cdf0e10cSrcweir 
141cdf0e10cSrcweir /*************************************************************************
142cdf0e10cSrcweir |*
143cdf0e10cSrcweir |* Ctor
144cdf0e10cSrcweir |*
145cdf0e10cSrcweir \************************************************************************/
146cdf0e10cSrcweir 
147cdf0e10cSrcweir Outliner::Outliner( SdDrawDocument* pDoc, sal_uInt16 nMode )
148cdf0e10cSrcweir     : SdrOutliner( &pDoc->GetItemPool(), nMode ),
149cdf0e10cSrcweir       mpImpl(new Implementation()),
150cdf0e10cSrcweir       meMode(SEARCH),
151cdf0e10cSrcweir       mpView(NULL),
152967189efSMichael Stahl       mpWeakViewShell(),
153cdf0e10cSrcweir       mpWindow(NULL),
154cdf0e10cSrcweir       mpDrawDocument(pDoc),
155cdf0e10cSrcweir       mnConversionLanguage(LANGUAGE_NONE),
156cdf0e10cSrcweir       mnIgnoreCurrentPageChangesLevel(0),
157cdf0e10cSrcweir       mbStringFound(sal_False),
158cdf0e10cSrcweir       mbMatchMayExist(false),
159cdf0e10cSrcweir       mnPageCount(0),
160cdf0e10cSrcweir       mnObjectCount(0),
161cdf0e10cSrcweir       mbEndOfSearch(sal_False),
162cdf0e10cSrcweir       mbFoundObject(sal_False),
163cdf0e10cSrcweir       mbError(sal_False),
164cdf0e10cSrcweir       mbDirectionIsForward(true),
165cdf0e10cSrcweir       mbRestrictSearchToSelection(false),
166cdf0e10cSrcweir       maMarkListCopy(),
167cdf0e10cSrcweir       mbProcessCurrentViewOnly(false),
168cdf0e10cSrcweir       mpObj(NULL),
169cdf0e10cSrcweir       mpFirstObj(NULL),
170cdf0e10cSrcweir       mpTextObj(NULL),
171cdf0e10cSrcweir       mnText(0),
172cdf0e10cSrcweir       mpParaObj(NULL),
173cdf0e10cSrcweir       meStartViewMode(PK_STANDARD),
174cdf0e10cSrcweir       meStartEditMode(EM_PAGE),
175cdf0e10cSrcweir       mnStartPageIndex((sal_uInt16)-1),
176cdf0e10cSrcweir       mpStartEditedObject(NULL),
177cdf0e10cSrcweir       maStartSelection(),
178cdf0e10cSrcweir       mpSearchItem(NULL),
179cdf0e10cSrcweir       maObjectIterator(),
180cdf0e10cSrcweir       maCurrentPosition(),
181cdf0e10cSrcweir       maSearchStartPosition(),
182cdf0e10cSrcweir       maLastValidPosition(),
183cdf0e10cSrcweir       mbSelectionHasChanged(false),
184cdf0e10cSrcweir       mbExpectingSelectionChangeEvent(false),
185cdf0e10cSrcweir       mbWholeDocumentProcessed(false),
186967189efSMichael Stahl       mbPrepareSpellingPending(true)
187cdf0e10cSrcweir {
188cdf0e10cSrcweir     SetStyleSheetPool((SfxStyleSheetPool*) mpDrawDocument->GetStyleSheetPool());
189cdf0e10cSrcweir     SetEditTextObjectPool( &pDoc->GetItemPool() );
190cdf0e10cSrcweir     SetCalcFieldValueHdl(LINK(SD_MOD(), SdModule, CalcFieldValueHdl));
191cdf0e10cSrcweir     SetForbiddenCharsTable( pDoc->GetForbiddenCharsTable() );
192cdf0e10cSrcweir 
193cdf0e10cSrcweir     sal_uLong nCntrl = GetControlWord();
194cdf0e10cSrcweir     nCntrl |= EE_CNTRL_ALLOWBIGOBJS;
195cdf0e10cSrcweir     nCntrl |= EE_CNTRL_URLSFXEXECUTE;
196cdf0e10cSrcweir     nCntrl |= EE_CNTRL_MARKFIELDS;
197cdf0e10cSrcweir     nCntrl |= EE_CNTRL_AUTOCORRECT;
198cdf0e10cSrcweir 
199cdf0e10cSrcweir     sal_Bool bOnlineSpell = false;
200cdf0e10cSrcweir 
201cdf0e10cSrcweir     DrawDocShell* pDocSh = mpDrawDocument->GetDocSh();
202cdf0e10cSrcweir 
203cdf0e10cSrcweir     if (pDocSh)
204cdf0e10cSrcweir     {
205cdf0e10cSrcweir         bOnlineSpell = mpDrawDocument->GetOnlineSpell();
206cdf0e10cSrcweir     }
207cdf0e10cSrcweir     else
208cdf0e10cSrcweir     {
209cdf0e10cSrcweir         bOnlineSpell = false;
210cdf0e10cSrcweir 
211cdf0e10cSrcweir         try
212cdf0e10cSrcweir         {
213cdf0e10cSrcweir             const SvtLinguConfig    aLinguConfig;
214cdf0e10cSrcweir             Any                     aAny;
215cdf0e10cSrcweir 
216cdf0e10cSrcweir             aAny = aLinguConfig.GetProperty(
217cdf0e10cSrcweir                 rtl::OUString::createFromAscii( UPN_IS_SPELL_AUTO ) );
218cdf0e10cSrcweir             aAny >>= bOnlineSpell;
219cdf0e10cSrcweir         }
220cdf0e10cSrcweir         catch( ... )
221cdf0e10cSrcweir         {
222cdf0e10cSrcweir             DBG_ERROR( "Ill. type in linguistic property" );
223cdf0e10cSrcweir         }
224cdf0e10cSrcweir     }
225cdf0e10cSrcweir 
226cdf0e10cSrcweir     if (bOnlineSpell)
227cdf0e10cSrcweir         nCntrl |= EE_CNTRL_ONLINESPELLING;
228cdf0e10cSrcweir     else
229cdf0e10cSrcweir         nCntrl &= ~EE_CNTRL_ONLINESPELLING;
230cdf0e10cSrcweir 
231cdf0e10cSrcweir     SetControlWord(nCntrl);
232cdf0e10cSrcweir 
233cdf0e10cSrcweir     Reference< XSpellChecker1 > xSpellChecker( LinguMgr::GetSpellChecker() );
234cdf0e10cSrcweir     if ( xSpellChecker.is() )
235cdf0e10cSrcweir         SetSpeller( xSpellChecker );
236cdf0e10cSrcweir 
237cdf0e10cSrcweir     Reference< XHyphenator > xHyphenator( LinguMgr::GetHyphenator() );
238cdf0e10cSrcweir     if( xHyphenator.is() )
239cdf0e10cSrcweir         SetHyphenator( xHyphenator );
240cdf0e10cSrcweir 
241cdf0e10cSrcweir     SetDefaultLanguage( Application::GetSettings().GetLanguage() );
242cdf0e10cSrcweir }
243cdf0e10cSrcweir 
244cdf0e10cSrcweir 
245cdf0e10cSrcweir 
246cdf0e10cSrcweir 
247cdf0e10cSrcweir /// Nothing spectecular in the destructor.
248cdf0e10cSrcweir Outliner::~Outliner (void)
249cdf0e10cSrcweir {
250cdf0e10cSrcweir     mpImpl.reset();
251cdf0e10cSrcweir }
252cdf0e10cSrcweir 
253cdf0e10cSrcweir 
254cdf0e10cSrcweir 
255cdf0e10cSrcweir 
256cdf0e10cSrcweir /** Prepare find&replace or spellchecking.  This distinguishes between three
257cdf0e10cSrcweir     cases:
258cdf0e10cSrcweir     <ol>
259cdf0e10cSrcweir     <li>The current shell is a <type>DrawViewShell</type>: Create a
260cdf0e10cSrcweir     <type>OutlinerView</type> object and search all objects of (i) the
261cdf0e10cSrcweir     current mark list, (ii) of the current view, or (iii) of all the view
262cdf0e10cSrcweir     combinations:
263cdf0e10cSrcweir     <ol>
264cdf0e10cSrcweir     <li>Draw view, slide view</li>
265cdf0e10cSrcweir     <li>Draw view, background view</li>
266cdf0e10cSrcweir     <li>Notes view, slide view</li>
267cdf0e10cSrcweir     <li>Notes view, background view</li>
268cdf0e10cSrcweir     <li>Handout view, slide view</li>
269cdf0e10cSrcweir     <li>Handout view, background view</li>
270cdf0e10cSrcweir     </ol>
271cdf0e10cSrcweir 
272cdf0e10cSrcweir     <li>When the current shell is a <type>SdOutlineViewShell</type> then
273cdf0e10cSrcweir     directly operate on it.  No switching into other views takes place.</li>
274cdf0e10cSrcweir 
275cdf0e10cSrcweir     <li>For a <type>SlideViewShell</type> no action is performed.</li>
276cdf0e10cSrcweir     </ol>
277cdf0e10cSrcweir */
278cdf0e10cSrcweir void Outliner::PrepareSpelling (void)
279cdf0e10cSrcweir {
280cdf0e10cSrcweir     mbPrepareSpellingPending = false;
281cdf0e10cSrcweir 
282cdf0e10cSrcweir     ViewShellBase* pBase = PTR_CAST(ViewShellBase,SfxViewShell::Current());
283cdf0e10cSrcweir     if (pBase != NULL)
284cdf0e10cSrcweir         SetViewShell (pBase->GetMainViewShell());
285cdf0e10cSrcweir     SetRefDevice( SD_MOD()->GetRefDevice( *mpDrawDocument->GetDocSh() ) );
286cdf0e10cSrcweir 
287967189efSMichael Stahl     ::boost::shared_ptr<ViewShell> pViewShell (mpWeakViewShell.lock());
288967189efSMichael Stahl     if (pViewShell)
289cdf0e10cSrcweir     {
290cdf0e10cSrcweir         mbStringFound = sal_False;
291cdf0e10cSrcweir 
292cdf0e10cSrcweir         mbWholeDocumentProcessed = false;
293cdf0e10cSrcweir         // Supposed that we are not located at the very beginning/end of
294cdf0e10cSrcweir         // the document then there may be a match in the document
295cdf0e10cSrcweir         // prior/after the current position.
296cdf0e10cSrcweir         mbMatchMayExist = sal_True;
297cdf0e10cSrcweir 
298cdf0e10cSrcweir         maObjectIterator = ::sd::outliner::Iterator();
299cdf0e10cSrcweir         maSearchStartPosition = ::sd::outliner::Iterator();
300cdf0e10cSrcweir         RememberStartPosition();
301cdf0e10cSrcweir 
302967189efSMichael Stahl         mpImpl->ProvideOutlinerView(*this, pViewShell, mpWindow);
303cdf0e10cSrcweir 
304cdf0e10cSrcweir         HandleChangedSelection ();
305cdf0e10cSrcweir     }
306cdf0e10cSrcweir     ClearModifyFlag();
307cdf0e10cSrcweir }
308cdf0e10cSrcweir 
309cdf0e10cSrcweir 
310cdf0e10cSrcweir 
311cdf0e10cSrcweir 
312cdf0e10cSrcweir 
313cdf0e10cSrcweir void Outliner::StartSpelling (void)
314cdf0e10cSrcweir {
315cdf0e10cSrcweir     meMode = SPELL;
316cdf0e10cSrcweir     mbDirectionIsForward = true;
317cdf0e10cSrcweir     mpSearchItem = NULL;
318cdf0e10cSrcweir }
319cdf0e10cSrcweir 
320cdf0e10cSrcweir /** Proxy for method from base class to avoid compiler warning */
321cdf0e10cSrcweir void Outliner::StartSpelling(EditView& rView, unsigned char c)
322cdf0e10cSrcweir {
323cdf0e10cSrcweir     SdrOutliner::StartSpelling( rView, c );
324cdf0e10cSrcweir }
325cdf0e10cSrcweir 
326cdf0e10cSrcweir /** Free all resources acquired during the search/spell check.  After a
327cdf0e10cSrcweir     spell check the start position is restored here.
328cdf0e10cSrcweir */
329cdf0e10cSrcweir void Outliner::EndSpelling (void)
330cdf0e10cSrcweir {
331cdf0e10cSrcweir     // Keep old view shell alive until we release the outliner view.
332967189efSMichael Stahl     ::boost::shared_ptr<ViewShell> pViewShell (mpWeakViewShell.lock());
333967189efSMichael Stahl     ::boost::shared_ptr<ViewShell> pOldViewShell (pViewShell);
334cdf0e10cSrcweir 
335cdf0e10cSrcweir     ViewShellBase* pBase = PTR_CAST(ViewShellBase,SfxViewShell::Current());
336cdf0e10cSrcweir     if (pBase != NULL)
337967189efSMichael Stahl         pViewShell = pBase->GetMainViewShell();
338cdf0e10cSrcweir     else
339967189efSMichael Stahl         pViewShell.reset();
340967189efSMichael Stahl     mpWeakViewShell = pViewShell;
341cdf0e10cSrcweir 
342cdf0e10cSrcweir     // When in <member>PrepareSpelling()</member> a new outline view has
343cdf0e10cSrcweir     // been created then delete it here.
344967189efSMichael Stahl     sal_Bool bViewIsDrawViewShell(pViewShell && pViewShell->ISA(DrawViewShell));
345cdf0e10cSrcweir     if (bViewIsDrawViewShell)
346cdf0e10cSrcweir     {
347cdf0e10cSrcweir         SetStatusEventHdl(Link());
348967189efSMichael Stahl         mpView = pViewShell->GetView();
349cdf0e10cSrcweir         mpView->UnmarkAllObj (mpView->GetSdrPageView());
350cdf0e10cSrcweir         mpView->SdrEndTextEdit();
351cdf0e10cSrcweir         // Make FuSelection the current function.
352967189efSMichael Stahl         pViewShell->GetDispatcher()->Execute(
353cdf0e10cSrcweir             SID_OBJECT_SELECT,
354cdf0e10cSrcweir             SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD);
355cdf0e10cSrcweir 
356cdf0e10cSrcweir         // Remove and, if previously created by us, delete the outline
357cdf0e10cSrcweir         // view.
358cdf0e10cSrcweir         OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
359cdf0e10cSrcweir         if (pOutlinerView != NULL)
360cdf0e10cSrcweir         {
361cdf0e10cSrcweir             RemoveView(pOutlinerView);
362cdf0e10cSrcweir             mpImpl->ReleaseOutlinerView();
363cdf0e10cSrcweir         }
364cdf0e10cSrcweir 
365cdf0e10cSrcweir         SetUpdateMode(sal_True);
366cdf0e10cSrcweir     }
367cdf0e10cSrcweir 
368cdf0e10cSrcweir     // #95811# Before clearing the modify flag use it as a hint that
369cdf0e10cSrcweir     // changes were done at SpellCheck
370cdf0e10cSrcweir     if(IsModified())
371cdf0e10cSrcweir     {
372cdf0e10cSrcweir         if(mpView && mpView->ISA(OutlineView))
373cdf0e10cSrcweir             static_cast<OutlineView*>(mpView)->PrepareClose(sal_False);
374cdf0e10cSrcweir         if(mpDrawDocument && !mpDrawDocument->IsChanged())
375cdf0e10cSrcweir             mpDrawDocument->SetChanged(sal_True);
376cdf0e10cSrcweir     }
377cdf0e10cSrcweir 
378cdf0e10cSrcweir     // #95811# now clear the modify flag to have a specified state of
379cdf0e10cSrcweir     // Outliner
380cdf0e10cSrcweir     ClearModifyFlag();
381cdf0e10cSrcweir 
382cdf0e10cSrcweir     // When spell checking then restore the start position.
383cdf0e10cSrcweir     if (meMode==SPELL || meMode==TEXT_CONVERSION)
384cdf0e10cSrcweir         RestoreStartPosition ();
385cdf0e10cSrcweir 
386967189efSMichael Stahl     mpWeakViewShell.reset();
387cdf0e10cSrcweir     mpView = NULL;
388cdf0e10cSrcweir     mpWindow = NULL;
389cdf0e10cSrcweir }
390cdf0e10cSrcweir 
391cdf0e10cSrcweir 
392cdf0e10cSrcweir 
393cdf0e10cSrcweir 
394cdf0e10cSrcweir sal_Bool Outliner::SpellNextDocument (void)
395cdf0e10cSrcweir {
396967189efSMichael Stahl     ::boost::shared_ptr<ViewShell> pViewShell (mpWeakViewShell.lock());
397967189efSMichael Stahl     if (pViewShell->ISA(OutlineViewShell))
398cdf0e10cSrcweir     {
399cdf0e10cSrcweir         // When doing a spell check in the outline view then there is
400cdf0e10cSrcweir         // only one document.
401cdf0e10cSrcweir         mbEndOfSearch = true;
402cdf0e10cSrcweir         EndOfSearch ();
403cdf0e10cSrcweir     }
404cdf0e10cSrcweir     else
405cdf0e10cSrcweir     {
406cdf0e10cSrcweir         if (mpView->ISA(OutlineView))
407cdf0e10cSrcweir             ((OutlineView*)mpView)->PrepareClose(sal_False);
408cdf0e10cSrcweir         mpDrawDocument->GetDocSh()->SetWaitCursor( sal_True );
409cdf0e10cSrcweir 
410cdf0e10cSrcweir         Initialize (true);
411cdf0e10cSrcweir 
412967189efSMichael Stahl         mpWindow = pViewShell->GetActiveWindow();
413cdf0e10cSrcweir         OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
414cdf0e10cSrcweir         if (pOutlinerView != NULL)
415cdf0e10cSrcweir             pOutlinerView->SetWindow(mpWindow);
416cdf0e10cSrcweir         ProvideNextTextObject ();
417cdf0e10cSrcweir 
418cdf0e10cSrcweir         mpDrawDocument->GetDocSh()->SetWaitCursor( sal_False );
419cdf0e10cSrcweir         ClearModifyFlag();
420cdf0e10cSrcweir     }
421cdf0e10cSrcweir 
422cdf0e10cSrcweir     return mbEndOfSearch ? sal_False : sal_True;
423cdf0e10cSrcweir 
424cdf0e10cSrcweir }
425cdf0e10cSrcweir 
426cdf0e10cSrcweir 
427cdf0e10cSrcweir /*************************************************************************
428cdf0e10cSrcweir |*
429cdf0e10cSrcweir |* Spelling: naechstes TextObjekt pruefen
430cdf0e10cSrcweir |*
431cdf0e10cSrcweir \************************************************************************/
432cdf0e10cSrcweir 
433cdf0e10cSrcweir ::svx::SpellPortions Outliner::GetNextSpellSentence (void)
434cdf0e10cSrcweir {
435cdf0e10cSrcweir     ::svx::SpellPortions aResult;
436cdf0e10cSrcweir 
437cdf0e10cSrcweir     DetectChange();
438cdf0e10cSrcweir     // Iterate over sentences and text shapes until a sentence with a
439cdf0e10cSrcweir     // spelling error has been found.  If no such sentence can be
440cdf0e10cSrcweir     // found the loop is left through a break.
441cdf0e10cSrcweir     // It is the responsibility of the sd outliner object to correctly
442cdf0e10cSrcweir     // iterate over all text shapes, i.e. switch between views, wrap
443cdf0e10cSrcweir     // arround at the end of the document, stop when all text shapes
444cdf0e10cSrcweir     // have been examined exactly once.
445cdf0e10cSrcweir     bool bFoundNextSentence = false;
446cdf0e10cSrcweir     while ( ! bFoundNextSentence)
447cdf0e10cSrcweir     {
448cdf0e10cSrcweir         OutlinerView* pOutlinerView = GetView(0);
449cdf0e10cSrcweir         if (pOutlinerView != NULL)
450cdf0e10cSrcweir         {
451cdf0e10cSrcweir             ESelection aCurrentSelection (pOutlinerView->GetSelection());
452cdf0e10cSrcweir             if ( ! mbMatchMayExist
453cdf0e10cSrcweir                 && maStartSelection.IsLess(aCurrentSelection))
454cdf0e10cSrcweir                 EndOfSearch();
455cdf0e10cSrcweir 
456cdf0e10cSrcweir             // Advance to the next sentence.
457cdf0e10cSrcweir             bFoundNextSentence = SpellSentence (
458cdf0e10cSrcweir                 pOutlinerView->GetEditView(),
459cdf0e10cSrcweir                 aResult, false);
460cdf0e10cSrcweir         }
461cdf0e10cSrcweir 
462cdf0e10cSrcweir         // When no sentence with spelling errors has been found in the
463cdf0e10cSrcweir         // currently selected text shape or there is no selected text
464cdf0e10cSrcweir         // shape then advance to the next text shape.
465cdf0e10cSrcweir         if ( ! bFoundNextSentence)
466cdf0e10cSrcweir             if ( ! SpellNextDocument())
467cdf0e10cSrcweir                 // All text objects have been processed so exit the
468cdf0e10cSrcweir                 // loop and return an empty portions list.
469cdf0e10cSrcweir                 break;
470cdf0e10cSrcweir     }
471cdf0e10cSrcweir 
472cdf0e10cSrcweir     return aResult;
473cdf0e10cSrcweir }
474cdf0e10cSrcweir 
475cdf0e10cSrcweir 
476cdf0e10cSrcweir 
477cdf0e10cSrcweir 
478cdf0e10cSrcweir /** Go to next match.
479cdf0e10cSrcweir */
480cdf0e10cSrcweir bool Outliner::StartSearchAndReplace (const SvxSearchItem* pSearchItem)
481cdf0e10cSrcweir {
482cdf0e10cSrcweir     sal_Bool bEndOfSearch = sal_True;
483cdf0e10cSrcweir 
484cdf0e10cSrcweir     mpDrawDocument->GetDocSh()->SetWaitCursor( sal_True );
485cdf0e10cSrcweir     if (mbPrepareSpellingPending)
486cdf0e10cSrcweir         PrepareSpelling();
487cdf0e10cSrcweir     ViewShellBase* pBase = PTR_CAST(ViewShellBase,SfxViewShell::Current());
488cdf0e10cSrcweir     // Determine whether we have to abort the search.  This is necessary
489cdf0e10cSrcweir     // when the main view shell does not support searching.
490cdf0e10cSrcweir     bool bAbort = false;
491cdf0e10cSrcweir     if (pBase != NULL)
492cdf0e10cSrcweir     {
493cdf0e10cSrcweir         ::boost::shared_ptr<ViewShell> pShell (pBase->GetMainViewShell());
494cdf0e10cSrcweir         SetViewShell(pShell);
495cdf0e10cSrcweir         if (pShell.get() == NULL)
496cdf0e10cSrcweir             bAbort = true;
497cdf0e10cSrcweir         else
498cdf0e10cSrcweir             switch (pShell->GetShellType())
499cdf0e10cSrcweir             {
500cdf0e10cSrcweir                 case ViewShell::ST_DRAW:
501cdf0e10cSrcweir                 case ViewShell::ST_IMPRESS:
502cdf0e10cSrcweir                 case ViewShell::ST_NOTES:
503cdf0e10cSrcweir                 case ViewShell::ST_HANDOUT:
504cdf0e10cSrcweir                 case ViewShell::ST_OUTLINE:
505cdf0e10cSrcweir                     bAbort = false;
506cdf0e10cSrcweir                     break;
507cdf0e10cSrcweir                 default:
508cdf0e10cSrcweir                     bAbort = true;
509cdf0e10cSrcweir                     break;
510cdf0e10cSrcweir             }
511cdf0e10cSrcweir     }
512cdf0e10cSrcweir 
513967189efSMichael Stahl     ::boost::shared_ptr<ViewShell> pViewShell (mpWeakViewShell.lock());
514967189efSMichael Stahl     if ( ! pViewShell)
515967189efSMichael Stahl     {
516967189efSMichael Stahl         OSL_ASSERT(pViewShell);
517967189efSMichael Stahl         return true;
518967189efSMichael Stahl     }
519967189efSMichael Stahl 
520cdf0e10cSrcweir     if ( ! bAbort)
521cdf0e10cSrcweir     {
522cdf0e10cSrcweir         meMode = SEARCH;
523cdf0e10cSrcweir         mpSearchItem = pSearchItem;
524cdf0e10cSrcweir 
525cdf0e10cSrcweir         mbFoundObject = sal_False;
526cdf0e10cSrcweir 
527cdf0e10cSrcweir         Initialize ( ! mpSearchItem->GetBackward());
528cdf0e10cSrcweir 
529*60b45af2SMichael Stahl         const sal_uInt16 nCommand (mpSearchItem->GetCommand());
530cdf0e10cSrcweir         if (nCommand == SVX_SEARCHCMD_REPLACE_ALL)
531cdf0e10cSrcweir             bEndOfSearch = SearchAndReplaceAll ();
532cdf0e10cSrcweir         else
533cdf0e10cSrcweir         {
534cdf0e10cSrcweir             RememberStartPosition ();
535cdf0e10cSrcweir             bEndOfSearch = SearchAndReplaceOnce ();
536cdf0e10cSrcweir             //#107233# restore start position if nothing was found
537cdf0e10cSrcweir             if(!mbStringFound)
538cdf0e10cSrcweir                 RestoreStartPosition ();
539cdf0e10cSrcweir             else
540cdf0e10cSrcweir                 mnStartPageIndex = (sal_uInt16)-1;
541cdf0e10cSrcweir         }
542cdf0e10cSrcweir     }
543cdf0e10cSrcweir     else
544cdf0e10cSrcweir         mpDrawDocument->GetDocSh()->SetWaitCursor( sal_False );
545cdf0e10cSrcweir 
546cdf0e10cSrcweir     return bEndOfSearch;
547cdf0e10cSrcweir }
548cdf0e10cSrcweir 
549cdf0e10cSrcweir 
550cdf0e10cSrcweir 
551cdf0e10cSrcweir 
552cdf0e10cSrcweir void Outliner::Initialize (bool bDirectionIsForward)
553cdf0e10cSrcweir {
554cdf0e10cSrcweir     const bool bIsAtEnd (maObjectIterator == ::sd::outliner::OutlinerContainer(this).end());
555cdf0e10cSrcweir     const bool bOldDirectionIsForward = mbDirectionIsForward;
556cdf0e10cSrcweir     mbDirectionIsForward = bDirectionIsForward;
557cdf0e10cSrcweir 
558cdf0e10cSrcweir     if (maObjectIterator == ::sd::outliner::Iterator())
559cdf0e10cSrcweir     {
560cdf0e10cSrcweir         // Initialize a new search.
561cdf0e10cSrcweir         maObjectIterator = ::sd::outliner::OutlinerContainer(this).current();
562cdf0e10cSrcweir         maCurrentPosition = *maObjectIterator;
563cdf0e10cSrcweir 
564967189efSMichael Stahl         ::boost::shared_ptr<ViewShell> pViewShell (mpWeakViewShell.lock());
565967189efSMichael Stahl         if ( ! pViewShell)
566967189efSMichael Stahl         {
567967189efSMichael Stahl             OSL_ASSERT(pViewShell);
568967189efSMichael Stahl             return;
569967189efSMichael Stahl         }
570967189efSMichael Stahl 
571cdf0e10cSrcweir         // In case we are searching in an outline view then first remove the
572cdf0e10cSrcweir         // current selection and place cursor at its start or end.
573967189efSMichael Stahl         if (pViewShell->ISA(OutlineViewShell))
574cdf0e10cSrcweir         {
575cdf0e10cSrcweir             ESelection aSelection = mpImpl->GetOutlinerView()->GetSelection ();
576cdf0e10cSrcweir             if (mbDirectionIsForward)
577cdf0e10cSrcweir             {
578cdf0e10cSrcweir                 aSelection.nEndPara = aSelection.nStartPara;
579cdf0e10cSrcweir                 aSelection.nEndPos = aSelection.nStartPos;
580cdf0e10cSrcweir             }
581cdf0e10cSrcweir             else
582cdf0e10cSrcweir             {
583cdf0e10cSrcweir                 aSelection.nStartPara = aSelection.nEndPara;
584cdf0e10cSrcweir                 aSelection.nStartPos = aSelection.nEndPos;
585cdf0e10cSrcweir             }
586cdf0e10cSrcweir             mpImpl->GetOutlinerView()->SetSelection (aSelection);
587cdf0e10cSrcweir         }
588cdf0e10cSrcweir 
589cdf0e10cSrcweir         // When not beginning the search at the beginning of the search area
590cdf0e10cSrcweir         // then there may be matches before the current position.
591cdf0e10cSrcweir         mbMatchMayExist = (maObjectIterator!=::sd::outliner::OutlinerContainer(this).begin());
592cdf0e10cSrcweir     }
593cdf0e10cSrcweir     else if (bOldDirectionIsForward != mbDirectionIsForward)
594cdf0e10cSrcweir     {
595cdf0e10cSrcweir         // Requested iteration direction has changed.  Turn arround the iterator.
596cdf0e10cSrcweir         maObjectIterator.Reverse();
597cdf0e10cSrcweir         if (bIsAtEnd)
598cdf0e10cSrcweir         {
599cdf0e10cSrcweir             // The iterator has pointed to end(), which after the search
600cdf0e10cSrcweir             // direction is reversed, becomes begin().
601cdf0e10cSrcweir             maObjectIterator = ::sd::outliner::OutlinerContainer(this).begin();
602cdf0e10cSrcweir         }
603cdf0e10cSrcweir         else
604cdf0e10cSrcweir         {
605cdf0e10cSrcweir             // The iterator has pointed to the object one ahead/before the current
606cdf0e10cSrcweir             // one.  Now move it to the one before/ahead the current one.
607cdf0e10cSrcweir             ++maObjectIterator;
608cdf0e10cSrcweir             ++maObjectIterator;
609cdf0e10cSrcweir         }
610cdf0e10cSrcweir 
611cdf0e10cSrcweir         mbMatchMayExist = true;
612cdf0e10cSrcweir     }
613cdf0e10cSrcweir 
614cdf0e10cSrcweir     // Initialize the last valid position with where the search starts so
615cdf0e10cSrcweir     // that it always points to a valid position.
616cdf0e10cSrcweir     maLastValidPosition = *::sd::outliner::OutlinerContainer(this).current();
617cdf0e10cSrcweir }
618cdf0e10cSrcweir 
619cdf0e10cSrcweir 
620cdf0e10cSrcweir 
621cdf0e10cSrcweir 
622cdf0e10cSrcweir bool Outliner::SearchAndReplaceAll (void)
623cdf0e10cSrcweir {
624cdf0e10cSrcweir     // Save the current position to be restored after having replaced all
625cdf0e10cSrcweir     // matches.
626cdf0e10cSrcweir     RememberStartPosition ();
627cdf0e10cSrcweir 
628967189efSMichael Stahl     ::boost::shared_ptr<ViewShell> pViewShell (mpWeakViewShell.lock());
629967189efSMichael Stahl     if ( ! pViewShell)
630967189efSMichael Stahl     {
631967189efSMichael Stahl         OSL_ASSERT(pViewShell);
632967189efSMichael Stahl         return true;
633967189efSMichael Stahl     }
634967189efSMichael Stahl 
635967189efSMichael Stahl     if (pViewShell->ISA(OutlineViewShell))
636cdf0e10cSrcweir     {
637cdf0e10cSrcweir         // Put the cursor to the beginning/end of the outliner.
638cdf0e10cSrcweir         mpImpl->GetOutlinerView()->SetSelection (GetSearchStartPosition ());
639cdf0e10cSrcweir 
640cdf0e10cSrcweir         // The outliner does all the work for us when we are in this mode.
641cdf0e10cSrcweir         SearchAndReplaceOnce();
642cdf0e10cSrcweir     }
643967189efSMichael Stahl     else if (pViewShell->ISA(DrawViewShell))
644cdf0e10cSrcweir     {
645cdf0e10cSrcweir         // Go to beginning/end of document.
646cdf0e10cSrcweir         maObjectIterator = ::sd::outliner::OutlinerContainer(this).begin();
647cdf0e10cSrcweir         // Switch to the current object only if it is a valid text object.
648cdf0e10cSrcweir         ::sd::outliner::IteratorPosition aNewPosition (*maObjectIterator);
649cdf0e10cSrcweir         if (IsValidTextObject (aNewPosition))
650cdf0e10cSrcweir         {
651cdf0e10cSrcweir             maCurrentPosition = aNewPosition;
652cdf0e10cSrcweir             SetObject (maCurrentPosition);
653cdf0e10cSrcweir         }
654cdf0e10cSrcweir 
655cdf0e10cSrcweir         // Search/replace until the end of the document is reached.
656cdf0e10cSrcweir         bool bFoundMatch;
657cdf0e10cSrcweir         do
658cdf0e10cSrcweir         {
659cdf0e10cSrcweir             bFoundMatch = ! SearchAndReplaceOnce();
660cdf0e10cSrcweir         }
661cdf0e10cSrcweir         while (bFoundMatch);
662cdf0e10cSrcweir     }
663cdf0e10cSrcweir 
664cdf0e10cSrcweir     RestoreStartPosition ();
665cdf0e10cSrcweir 
666cdf0e10cSrcweir     return true;
667cdf0e10cSrcweir }
668cdf0e10cSrcweir 
669cdf0e10cSrcweir 
670cdf0e10cSrcweir 
671cdf0e10cSrcweir 
672cdf0e10cSrcweir bool Outliner::SearchAndReplaceOnce (void)
673cdf0e10cSrcweir {
674cdf0e10cSrcweir     DetectChange ();
675cdf0e10cSrcweir 
676cdf0e10cSrcweir     OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
677cdf0e10cSrcweir     DBG_ASSERT(pOutlinerView!=NULL && GetEditEngine().HasView( &pOutlinerView->GetEditView() ),
678cdf0e10cSrcweir         "SearchAndReplace without valid view!" );
679cdf0e10cSrcweir 
680cdf0e10cSrcweir     if( NULL == pOutlinerView || !GetEditEngine().HasView( &pOutlinerView->GetEditView() ) )
681cdf0e10cSrcweir         return true;
682cdf0e10cSrcweir 
683967189efSMichael Stahl     ::boost::shared_ptr<ViewShell> pViewShell (mpWeakViewShell.lock());
684967189efSMichael Stahl     if (pViewShell != NULL)
685cdf0e10cSrcweir     {
686967189efSMichael Stahl         mpView = pViewShell->GetView();
687967189efSMichael Stahl         mpWindow = pViewShell->GetActiveWindow();
688cdf0e10cSrcweir         pOutlinerView->SetWindow(mpWindow);
689cdf0e10cSrcweir 
690967189efSMichael Stahl         if (pViewShell->ISA(DrawViewShell) )
691cdf0e10cSrcweir         {
692cdf0e10cSrcweir             // When replacing we first check if there is a selection
693cdf0e10cSrcweir             // indicating a match.  If there is then replace it.  The
694cdf0e10cSrcweir             // following call to StartSearchAndReplace will then search for
695cdf0e10cSrcweir             // the next match.
696cdf0e10cSrcweir             if (meMode == SEARCH
697cdf0e10cSrcweir                 && mpSearchItem->GetCommand() == SVX_SEARCHCMD_REPLACE)
698cdf0e10cSrcweir                 if (pOutlinerView->GetSelection().HasRange())
699cdf0e10cSrcweir                     pOutlinerView->StartSearchAndReplace(*mpSearchItem);
700cdf0e10cSrcweir 
701cdf0e10cSrcweir             // Search for the next match.
702cdf0e10cSrcweir             sal_uLong nMatchCount = 0;
703cdf0e10cSrcweir             if (mpSearchItem->GetCommand() != SVX_SEARCHCMD_REPLACE_ALL)
704cdf0e10cSrcweir                 nMatchCount = pOutlinerView->StartSearchAndReplace(*mpSearchItem);
705cdf0e10cSrcweir 
706cdf0e10cSrcweir             // Go to the next text object when there have been no matches in
707cdf0e10cSrcweir             // the current object or the whole object has already been
708cdf0e10cSrcweir             // processed.
709cdf0e10cSrcweir             if (nMatchCount==0 || mpSearchItem->GetCommand()==SVX_SEARCHCMD_REPLACE_ALL)
710cdf0e10cSrcweir             {
711cdf0e10cSrcweir                 ProvideNextTextObject ();
712cdf0e10cSrcweir 
713cdf0e10cSrcweir                 if ( ! mbEndOfSearch)
714cdf0e10cSrcweir                 {
715cdf0e10cSrcweir                     // Remember the current position as the last one with a
716cdf0e10cSrcweir                     // text object.
717cdf0e10cSrcweir                     maLastValidPosition = maCurrentPosition;
718cdf0e10cSrcweir 
719cdf0e10cSrcweir                     // Now that the mbEndOfSearch flag guards this block the
720cdf0e10cSrcweir                     // following assertion and return should not be
721cdf0e10cSrcweir                     // necessary anymore.
722cdf0e10cSrcweir                     DBG_ASSERT(GetEditEngine().HasView(&pOutlinerView->GetEditView() ),
723cdf0e10cSrcweir                         "SearchAndReplace without valid view!" );
724cdf0e10cSrcweir                     if ( ! GetEditEngine().HasView( &pOutlinerView->GetEditView() ) )
725cdf0e10cSrcweir                     {
726cdf0e10cSrcweir                         mpDrawDocument->GetDocSh()->SetWaitCursor( sal_False );
727cdf0e10cSrcweir                         return true;
728cdf0e10cSrcweir                     }
729cdf0e10cSrcweir 
730cdf0e10cSrcweir                     if (meMode == SEARCH)
731cdf0e10cSrcweir                         nMatchCount = pOutlinerView->StartSearchAndReplace(*mpSearchItem);
732cdf0e10cSrcweir                 }
733cdf0e10cSrcweir             }
734cdf0e10cSrcweir         }
735967189efSMichael Stahl         else if (pViewShell->ISA(OutlineViewShell))
736cdf0e10cSrcweir         {
737cdf0e10cSrcweir             mpDrawDocument->GetDocSh()->SetWaitCursor (sal_False);
738cdf0e10cSrcweir             // The following loop is executed more then once only when a
739cdf0e10cSrcweir             // wrap arround search is done.
740cdf0e10cSrcweir             while (true)
741cdf0e10cSrcweir             {
742cdf0e10cSrcweir                 int nResult = pOutlinerView->StartSearchAndReplace(*mpSearchItem);
743cdf0e10cSrcweir                 if (nResult == 0)
744cdf0e10cSrcweir                 {
745cdf0e10cSrcweir                     if (HandleFailedSearch ())
746cdf0e10cSrcweir                     {
747cdf0e10cSrcweir                         pOutlinerView->SetSelection (GetSearchStartPosition ());
748cdf0e10cSrcweir                         continue;
749cdf0e10cSrcweir                     }
750cdf0e10cSrcweir                 }
751cdf0e10cSrcweir                 else
752cdf0e10cSrcweir                     mbStringFound = true;
753cdf0e10cSrcweir                 break;
754cdf0e10cSrcweir             }
755cdf0e10cSrcweir         }
756cdf0e10cSrcweir     }
757cdf0e10cSrcweir 
758cdf0e10cSrcweir     mpDrawDocument->GetDocSh()->SetWaitCursor( sal_False );
759cdf0e10cSrcweir 
760cdf0e10cSrcweir     return mbEndOfSearch;
761cdf0e10cSrcweir }
762cdf0e10cSrcweir 
763cdf0e10cSrcweir 
764cdf0e10cSrcweir 
765cdf0e10cSrcweir 
766cdf0e10cSrcweir /** Try to detect whether the document or the view (shell) has changed since
767cdf0e10cSrcweir     the last time <member>StartSearchAndReplace()</member> has been called.
768cdf0e10cSrcweir */
769cdf0e10cSrcweir void Outliner::DetectChange (void)
770cdf0e10cSrcweir {
771cdf0e10cSrcweir     ::sd::outliner::IteratorPosition aPosition (maCurrentPosition);
772cdf0e10cSrcweir 
773967189efSMichael Stahl     ::boost::shared_ptr<ViewShell> pViewShell (mpWeakViewShell.lock());
774cdf0e10cSrcweir     ::boost::shared_ptr<DrawViewShell> pDrawViewShell (
775967189efSMichael Stahl         ::boost::dynamic_pointer_cast<DrawViewShell>(pViewShell));
776cdf0e10cSrcweir 
777cdf0e10cSrcweir     // Detect whether the view has been switched from the outside.
778cdf0e10cSrcweir     if (pDrawViewShell.get() != NULL
779cdf0e10cSrcweir         && (aPosition.meEditMode != pDrawViewShell->GetEditMode()
780cdf0e10cSrcweir             || aPosition.mePageKind != pDrawViewShell->GetPageKind()))
781cdf0e10cSrcweir     {
782cdf0e10cSrcweir         // Either the edit mode or the page kind has changed.
783cdf0e10cSrcweir         SetStatusEventHdl(Link());
784cdf0e10cSrcweir 
785cdf0e10cSrcweir         SdrPageView* pPageView = mpView->GetSdrPageView();
786cdf0e10cSrcweir         if (pPageView != NULL)
787cdf0e10cSrcweir             mpView->UnmarkAllObj (pPageView);
788cdf0e10cSrcweir         mpView->SdrEndTextEdit();
789cdf0e10cSrcweir         SetUpdateMode(sal_False);
790cdf0e10cSrcweir         OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
791cdf0e10cSrcweir         if (pOutlinerView != NULL)
792cdf0e10cSrcweir             pOutlinerView->SetOutputArea( Rectangle( Point(), Size(1, 1) ) );
793cdf0e10cSrcweir         if (meMode == SPELL)
794cdf0e10cSrcweir             SetPaperSize( Size(1, 1) );
795cdf0e10cSrcweir         SetText( String(), GetParagraph( 0 ) );
796cdf0e10cSrcweir 
797cdf0e10cSrcweir         RememberStartPosition ();
798cdf0e10cSrcweir 
799cdf0e10cSrcweir         mnPageCount = mpDrawDocument->GetSdPageCount(pDrawViewShell->GetPageKind());
800cdf0e10cSrcweir         maObjectIterator = ::sd::outliner::OutlinerContainer(this).current();
801cdf0e10cSrcweir     }
802cdf0e10cSrcweir 
803cdf0e10cSrcweir     // Detect change of the set of selected objects.  If their number has
804cdf0e10cSrcweir     // changed start again with the first selected object.
805cdf0e10cSrcweir     else if (DetectSelectionChange())
806cdf0e10cSrcweir     {
807cdf0e10cSrcweir         HandleChangedSelection ();
808cdf0e10cSrcweir         maObjectIterator = ::sd::outliner::OutlinerContainer(this).current();
809cdf0e10cSrcweir     }
810cdf0e10cSrcweir 
811cdf0e10cSrcweir     // Detect change of page count.  Restart search at first/last page in
812cdf0e10cSrcweir     // that case.
813cdf0e10cSrcweir     else if (aPosition.meEditMode == EM_PAGE
814cdf0e10cSrcweir         && mpDrawDocument->GetSdPageCount(aPosition.mePageKind) != mnPageCount)
815cdf0e10cSrcweir     {
816cdf0e10cSrcweir         // The number of pages has changed.
817cdf0e10cSrcweir         mnPageCount = mpDrawDocument->GetSdPageCount(aPosition.mePageKind);
818cdf0e10cSrcweir         maObjectIterator = ::sd::outliner::OutlinerContainer(this).current();
819cdf0e10cSrcweir     }
820cdf0e10cSrcweir     else if (aPosition.meEditMode == EM_MASTERPAGE
821cdf0e10cSrcweir         && mpDrawDocument->GetSdPageCount(aPosition.mePageKind) != mnPageCount)
822cdf0e10cSrcweir     {
823cdf0e10cSrcweir         // The number of master pages has changed.
824cdf0e10cSrcweir         mnPageCount = mpDrawDocument->GetSdPageCount(aPosition.mePageKind);
825cdf0e10cSrcweir         maObjectIterator = ::sd::outliner::OutlinerContainer(this).current();
826cdf0e10cSrcweir     }
827cdf0e10cSrcweir }
828cdf0e10cSrcweir 
829cdf0e10cSrcweir 
830cdf0e10cSrcweir 
831cdf0e10cSrcweir 
832cdf0e10cSrcweir bool Outliner::DetectSelectionChange (void)
833cdf0e10cSrcweir {
834cdf0e10cSrcweir     bool bSelectionHasChanged = false;
835cdf0e10cSrcweir     sal_uLong nMarkCount = mpView->GetMarkedObjectList().GetMarkCount();
836cdf0e10cSrcweir 
837cdf0e10cSrcweir     // If mpObj is NULL then we have not yet found our first match.
838cdf0e10cSrcweir     // Detecting a change makes no sense.
839cdf0e10cSrcweir     if (mpObj != NULL)
840cdf0e10cSrcweir         switch (nMarkCount)
841cdf0e10cSrcweir         {
842cdf0e10cSrcweir             case 0:
843cdf0e10cSrcweir                 // The selection has changed when previously there have been
844cdf0e10cSrcweir                 // selected objects.
845cdf0e10cSrcweir                 bSelectionHasChanged = mbRestrictSearchToSelection;
846cdf0e10cSrcweir                 break;
847cdf0e10cSrcweir             case 1:
848cdf0e10cSrcweir                 // Check if the only selected object is not the one that we
849cdf0e10cSrcweir                 // had selected.
850cdf0e10cSrcweir                 if (mpView != NULL)
851cdf0e10cSrcweir                 {
852cdf0e10cSrcweir                     SdrMark* pMark = mpView->GetMarkedObjectList().GetMark(0);
853cdf0e10cSrcweir                     if (pMark != NULL)
854cdf0e10cSrcweir                         bSelectionHasChanged = (mpObj != pMark->GetMarkedSdrObj ());
855cdf0e10cSrcweir                 }
856cdf0e10cSrcweir                 break;
857cdf0e10cSrcweir             default:
858cdf0e10cSrcweir                 // We had selected exactly one object.
859cdf0e10cSrcweir                 bSelectionHasChanged = true;
860cdf0e10cSrcweir                 break;
861cdf0e10cSrcweir         }
862cdf0e10cSrcweir 
863cdf0e10cSrcweir     return bSelectionHasChanged;
864cdf0e10cSrcweir }
865cdf0e10cSrcweir 
866cdf0e10cSrcweir 
867cdf0e10cSrcweir 
868cdf0e10cSrcweir 
869cdf0e10cSrcweir void Outliner::RememberStartPosition (void)
870cdf0e10cSrcweir {
871967189efSMichael Stahl     ::boost::shared_ptr<ViewShell> pViewShell (mpWeakViewShell.lock());
872967189efSMichael Stahl     if ( ! pViewShell)
873967189efSMichael Stahl     {
874967189efSMichael Stahl         OSL_ASSERT(pViewShell);
875967189efSMichael Stahl         return;
876967189efSMichael Stahl     }
877967189efSMichael Stahl 
878967189efSMichael Stahl     if (pViewShell->ISA(DrawViewShell))
879cdf0e10cSrcweir     {
880cdf0e10cSrcweir         ::boost::shared_ptr<DrawViewShell> pDrawViewShell (
881967189efSMichael Stahl             ::boost::dynamic_pointer_cast<DrawViewShell>(pViewShell));
882cdf0e10cSrcweir         if (pDrawViewShell.get() != NULL)
883cdf0e10cSrcweir         {
884cdf0e10cSrcweir             meStartViewMode = pDrawViewShell->GetPageKind();
885cdf0e10cSrcweir             meStartEditMode = pDrawViewShell->GetEditMode();
886cdf0e10cSrcweir             mnStartPageIndex = pDrawViewShell->GetCurPageId() - 1;
887cdf0e10cSrcweir         }
888cdf0e10cSrcweir 
889cdf0e10cSrcweir         if (mpView != NULL)
890cdf0e10cSrcweir         {
891cdf0e10cSrcweir             mpStartEditedObject = mpView->GetTextEditObject();
892cdf0e10cSrcweir             if (mpStartEditedObject != NULL)
893cdf0e10cSrcweir             {
894cdf0e10cSrcweir                 // Try to retrieve current caret position only when there is an
895cdf0e10cSrcweir                 // edited object.
896cdf0e10cSrcweir                 ::Outliner* pOutliner =
897cdf0e10cSrcweir                     static_cast<DrawView*>(mpView)->GetTextEditOutliner();
898cdf0e10cSrcweir                 if (pOutliner!=NULL && pOutliner->GetViewCount()>0)
899cdf0e10cSrcweir                 {
900cdf0e10cSrcweir                     OutlinerView* pOutlinerView = pOutliner->GetView(0);
901cdf0e10cSrcweir                     maStartSelection = pOutlinerView->GetSelection();
902cdf0e10cSrcweir                 }
903cdf0e10cSrcweir             }
904cdf0e10cSrcweir         }
905cdf0e10cSrcweir     }
906967189efSMichael Stahl     else if (pViewShell->ISA(OutlineViewShell))
907cdf0e10cSrcweir     {
908cdf0e10cSrcweir         // Remember the current cursor position.
909cdf0e10cSrcweir         OutlinerView* pView = GetView(0);
910cdf0e10cSrcweir         if (pView != NULL)
911cdf0e10cSrcweir             pView->GetSelection();
912cdf0e10cSrcweir     }
913cdf0e10cSrcweir     else
914cdf0e10cSrcweir     {
915cdf0e10cSrcweir         mnStartPageIndex = (sal_uInt16)-1;
916cdf0e10cSrcweir     }
917cdf0e10cSrcweir }
918cdf0e10cSrcweir 
919cdf0e10cSrcweir 
920cdf0e10cSrcweir 
921cdf0e10cSrcweir 
922cdf0e10cSrcweir void Outliner::RestoreStartPosition (void)
923cdf0e10cSrcweir {
924cdf0e10cSrcweir     bool bRestore = true;
925cdf0e10cSrcweir     // Take a negative start page index as inidicator that restoring the
926cdf0e10cSrcweir     // start position is not requested.
927cdf0e10cSrcweir     if (mnStartPageIndex == (sal_uInt16)-1 )
928cdf0e10cSrcweir         bRestore = false;
929967189efSMichael Stahl     // Dont't restore when the view shell is not valid.
930967189efSMichael Stahl     ::boost::shared_ptr<ViewShell> pViewShell (mpWeakViewShell.lock());
931967189efSMichael Stahl     if (pViewShell == NULL)
932cdf0e10cSrcweir         bRestore = false;
933cdf0e10cSrcweir 
934cdf0e10cSrcweir     if (bRestore)
935cdf0e10cSrcweir     {
936967189efSMichael Stahl         if (pViewShell->ISA(DrawViewShell))
937cdf0e10cSrcweir         {
938cdf0e10cSrcweir             ::boost::shared_ptr<DrawViewShell> pDrawViewShell (
939967189efSMichael Stahl                 ::boost::dynamic_pointer_cast<DrawViewShell>(pViewShell));
940cdf0e10cSrcweir             SetViewMode (meStartViewMode);
941cdf0e10cSrcweir             if (pDrawViewShell.get() != NULL)
942cdf0e10cSrcweir                 SetPage (meStartEditMode, mnStartPageIndex);
943cdf0e10cSrcweir 
944cdf0e10cSrcweir 
945cdf0e10cSrcweir             if (mpStartEditedObject != NULL)
946cdf0e10cSrcweir             {
947cdf0e10cSrcweir                 // Turn on the text toolbar as it is done in FuText so that
948cdf0e10cSrcweir                 // undo manager setting/restoring in
949cdf0e10cSrcweir                 // sd::View::{Beg,End}TextEdit() works on the same view shell.
950967189efSMichael Stahl                 pViewShell->GetViewShellBase().GetToolBarManager()->SetToolBarShell(
951cdf0e10cSrcweir                     ToolBarManager::TBG_FUNCTION,
952cdf0e10cSrcweir                     RID_DRAW_TEXT_TOOLBOX);
953cdf0e10cSrcweir 
954cdf0e10cSrcweir                 mpView->SdrBeginTextEdit(mpStartEditedObject);
955cdf0e10cSrcweir                 ::Outliner* pOutliner =
956cdf0e10cSrcweir                       static_cast<DrawView*>(mpView)->GetTextEditOutliner();
957cdf0e10cSrcweir                 if (pOutliner!=NULL && pOutliner->GetViewCount()>0)
958cdf0e10cSrcweir                 {
959cdf0e10cSrcweir                     OutlinerView* pOutlinerView = pOutliner->GetView(0);
960cdf0e10cSrcweir                     pOutlinerView->SetSelection(maStartSelection);
961cdf0e10cSrcweir                 }
962cdf0e10cSrcweir             }
963cdf0e10cSrcweir         }
964967189efSMichael Stahl         else if (pViewShell->ISA(OutlineViewShell))
965cdf0e10cSrcweir         {
966cdf0e10cSrcweir             // Set cursor to its old position.
967cdf0e10cSrcweir             OutlinerView* pView = GetView(0);
968cdf0e10cSrcweir             if (pView != NULL)
969cdf0e10cSrcweir                 pView->SetSelection (maStartSelection);
970cdf0e10cSrcweir         }
971cdf0e10cSrcweir     }
972cdf0e10cSrcweir }
973cdf0e10cSrcweir 
974cdf0e10cSrcweir 
975cdf0e10cSrcweir 
976cdf0e10cSrcweir 
977cdf0e10cSrcweir /** The main purpose of this method is to iterate over all shape objects of
978cdf0e10cSrcweir     the search area (current selection, current view, or whole document)
979cdf0e10cSrcweir     until a text object has been found that contains at least one match or
980cdf0e10cSrcweir     until no such object can be found anymore.   These two conditions are
981cdf0e10cSrcweir     expressed by setting one of the flags <member>mbFoundObject</member> or
982cdf0e10cSrcweir     <member>mbEndOfSearch</member> to <TRUE/>.
983cdf0e10cSrcweir */
984cdf0e10cSrcweir void Outliner::ProvideNextTextObject (void)
985cdf0e10cSrcweir {
986cdf0e10cSrcweir     mbEndOfSearch = false;
987cdf0e10cSrcweir     mbFoundObject = false;
988cdf0e10cSrcweir 
989cdf0e10cSrcweir     mpView->UnmarkAllObj (mpView->GetSdrPageView());
990cdf0e10cSrcweir     try
991cdf0e10cSrcweir     {
992cdf0e10cSrcweir         mpView->SdrEndTextEdit();
993cdf0e10cSrcweir     }
994cdf0e10cSrcweir     catch (::com::sun::star::uno::Exception e)
995cdf0e10cSrcweir     {
996cdf0e10cSrcweir         DBG_UNHANDLED_EXCEPTION();
997cdf0e10cSrcweir     }
998cdf0e10cSrcweir     SetUpdateMode(sal_False);
999cdf0e10cSrcweir     OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
1000cdf0e10cSrcweir     if (pOutlinerView != NULL)
1001cdf0e10cSrcweir         pOutlinerView->SetOutputArea( Rectangle( Point(), Size(1, 1) ) );
1002cdf0e10cSrcweir     if (meMode == SPELL)
1003cdf0e10cSrcweir         SetPaperSize( Size(1, 1) );
1004cdf0e10cSrcweir     SetText( String(), GetParagraph( 0 ) );
1005cdf0e10cSrcweir 
1006cdf0e10cSrcweir     mpTextObj = NULL;
1007cdf0e10cSrcweir 
1008cdf0e10cSrcweir     // Iterate until a valid text object has been found or the search ends.
1009cdf0e10cSrcweir     do
1010cdf0e10cSrcweir     {
1011cdf0e10cSrcweir         mpObj = NULL;
1012cdf0e10cSrcweir         mpParaObj = NULL;
1013cdf0e10cSrcweir 
1014cdf0e10cSrcweir         if (maObjectIterator != ::sd::outliner::OutlinerContainer(this).end())
1015cdf0e10cSrcweir         {
1016cdf0e10cSrcweir             maCurrentPosition = *maObjectIterator;
1017cdf0e10cSrcweir             // Switch to the current object only if it is a valid text object.
1018cdf0e10cSrcweir             if (IsValidTextObject (maCurrentPosition))
1019cdf0e10cSrcweir             {
1020cdf0e10cSrcweir                 mpObj = SetObject (maCurrentPosition);
1021cdf0e10cSrcweir             }
1022cdf0e10cSrcweir             ++maObjectIterator;
1023cdf0e10cSrcweir 
1024cdf0e10cSrcweir             if (mpObj != NULL)
1025cdf0e10cSrcweir             {
1026cdf0e10cSrcweir                 PutTextIntoOutliner ();
1027cdf0e10cSrcweir 
1028967189efSMichael Stahl                 ::boost::shared_ptr<ViewShell> pViewShell (mpWeakViewShell.lock());
1029967189efSMichael Stahl                 if (pViewShell != NULL)
1030cdf0e10cSrcweir                     switch (meMode)
1031cdf0e10cSrcweir                     {
1032cdf0e10cSrcweir                         case SEARCH:
1033cdf0e10cSrcweir                             PrepareSearchAndReplace ();
1034cdf0e10cSrcweir                             break;
1035cdf0e10cSrcweir                         case SPELL:
1036cdf0e10cSrcweir                             PrepareSpellCheck ();
1037cdf0e10cSrcweir                             break;
1038cdf0e10cSrcweir                         case TEXT_CONVERSION:
1039cdf0e10cSrcweir                             PrepareConversion();
1040cdf0e10cSrcweir                             break;
1041cdf0e10cSrcweir                     }
1042cdf0e10cSrcweir             }
1043cdf0e10cSrcweir         }
1044cdf0e10cSrcweir         else
1045cdf0e10cSrcweir         {
1046cdf0e10cSrcweir             mbEndOfSearch = true;
1047cdf0e10cSrcweir             EndOfSearch ();
1048cdf0e10cSrcweir         }
1049cdf0e10cSrcweir     }
1050cdf0e10cSrcweir     while ( ! (mbFoundObject || mbEndOfSearch));
1051cdf0e10cSrcweir }
1052cdf0e10cSrcweir 
1053cdf0e10cSrcweir 
1054cdf0e10cSrcweir 
1055cdf0e10cSrcweir 
1056cdf0e10cSrcweir void Outliner::EndOfSearch (void)
1057cdf0e10cSrcweir {
1058967189efSMichael Stahl     ::boost::shared_ptr<ViewShell> pViewShell (mpWeakViewShell.lock());
1059967189efSMichael Stahl     if ( ! pViewShell)
1060967189efSMichael Stahl     {
1061967189efSMichael Stahl         OSL_ASSERT(pViewShell);
1062967189efSMichael Stahl         return;
1063967189efSMichael Stahl     }
1064967189efSMichael Stahl 
1065cdf0e10cSrcweir     // Before we display a dialog we first jump to where the last valid text
1066cdf0e10cSrcweir     // object was found.  All page and view mode switching since then was
1067cdf0e10cSrcweir     // temporary and should not be visible to the user.
1068967189efSMichael Stahl     if ( ! pViewShell->ISA(OutlineViewShell))
1069cdf0e10cSrcweir         SetObject (maLastValidPosition);
1070cdf0e10cSrcweir 
1071cdf0e10cSrcweir     if (mbRestrictSearchToSelection)
1072cdf0e10cSrcweir         ShowEndOfSearchDialog ();
1073cdf0e10cSrcweir     else
1074cdf0e10cSrcweir     {
1075cdf0e10cSrcweir         // When no match has been found so far then terminate the search.
1076cdf0e10cSrcweir         if ( ! mbMatchMayExist)
1077cdf0e10cSrcweir         {
1078cdf0e10cSrcweir             ShowEndOfSearchDialog ();
1079cdf0e10cSrcweir             mbEndOfSearch = sal_True;
1080cdf0e10cSrcweir         }
1081cdf0e10cSrcweir         // Ask the user whether to wrap arround and continue the search or
1082cdf0e10cSrcweir         // to terminate.
1083cdf0e10cSrcweir         else if (meMode==TEXT_CONVERSION || ShowWrapArroundDialog ())
1084cdf0e10cSrcweir         {
1085cdf0e10cSrcweir             mbMatchMayExist = false;
1086cdf0e10cSrcweir             // Everything back to beginning (or end?) of the document.
1087cdf0e10cSrcweir             maObjectIterator = ::sd::outliner::OutlinerContainer(this).begin();
1088967189efSMichael Stahl             if (pViewShell->ISA(OutlineViewShell))
1089cdf0e10cSrcweir             {
1090cdf0e10cSrcweir                 // Set cursor to first character of the document.
1091cdf0e10cSrcweir                 OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
1092cdf0e10cSrcweir                 if (pOutlinerView != NULL)
1093cdf0e10cSrcweir                     pOutlinerView->SetSelection (GetSearchStartPosition ());
1094cdf0e10cSrcweir             }
1095cdf0e10cSrcweir 
1096cdf0e10cSrcweir             mbEndOfSearch = false;
1097cdf0e10cSrcweir         }
1098cdf0e10cSrcweir         else
1099cdf0e10cSrcweir         {
1100cdf0e10cSrcweir             // No wrap arround.
1101cdf0e10cSrcweir             mbEndOfSearch = true;
1102cdf0e10cSrcweir         }
1103cdf0e10cSrcweir     }
1104cdf0e10cSrcweir }
1105cdf0e10cSrcweir 
1106cdf0e10cSrcweir void Outliner::ShowEndOfSearchDialog (void)
1107cdf0e10cSrcweir {
1108cdf0e10cSrcweir     String aString;
1109cdf0e10cSrcweir     if (meMode == SEARCH)
1110cdf0e10cSrcweir     {
1111cdf0e10cSrcweir         if (mbStringFound)
1112cdf0e10cSrcweir             aString = String( SdResId(STR_END_SEARCHING) );
1113cdf0e10cSrcweir         else
1114cdf0e10cSrcweir             aString = String( SdResId(STR_STRING_NOTFOUND) );
1115cdf0e10cSrcweir     }
1116cdf0e10cSrcweir     else
1117cdf0e10cSrcweir     {
1118cdf0e10cSrcweir         if (mpView->AreObjectsMarked())
1119cdf0e10cSrcweir             aString = String(SdResId(STR_END_SPELLING_OBJ));
1120cdf0e10cSrcweir         else
1121cdf0e10cSrcweir             aString = String(SdResId(STR_END_SPELLING));
1122cdf0e10cSrcweir     }
1123cdf0e10cSrcweir 
1124cdf0e10cSrcweir     // Show the message in an info box that is modal with respect to the
1125cdf0e10cSrcweir     // whole application.
1126cdf0e10cSrcweir     InfoBox aInfoBox (NULL, aString);
1127cdf0e10cSrcweir     ShowModalMessageBox (aInfoBox);
1128cdf0e10cSrcweir 
1129cdf0e10cSrcweir     mbWholeDocumentProcessed = true;
1130cdf0e10cSrcweir }
1131cdf0e10cSrcweir 
1132cdf0e10cSrcweir 
1133cdf0e10cSrcweir 
1134cdf0e10cSrcweir 
1135cdf0e10cSrcweir bool Outliner::ShowWrapArroundDialog (void)
1136cdf0e10cSrcweir {
1137cdf0e10cSrcweir     bool bDoWrapArround = false;
1138cdf0e10cSrcweir 
1139cdf0e10cSrcweir     // Determine whether to show the dialog.
1140cdf0e10cSrcweir     bool bShowDialog = false;
1141cdf0e10cSrcweir     if (mpSearchItem != NULL)
1142cdf0e10cSrcweir     {
1143cdf0e10cSrcweir         // When searching display the dialog only for single find&replace.
1144cdf0e10cSrcweir         sal_uInt16 nCommand = mpSearchItem->GetCommand();
1145cdf0e10cSrcweir         bShowDialog = (nCommand==SVX_SEARCHCMD_REPLACE)
1146cdf0e10cSrcweir             || (nCommand==SVX_SEARCHCMD_FIND);
1147cdf0e10cSrcweir     }
1148cdf0e10cSrcweir     else
1149cdf0e10cSrcweir         // Spell checking needs the dialog, too.
1150cdf0e10cSrcweir         bShowDialog = (meMode == SPELL);
1151cdf0e10cSrcweir 
1152cdf0e10cSrcweir     if (bShowDialog)
1153cdf0e10cSrcweir     {
1154cdf0e10cSrcweir         // The question text depends on the search direction.
1155cdf0e10cSrcweir         sal_Bool bImpress = mpDrawDocument!=NULL
1156cdf0e10cSrcweir             && mpDrawDocument->GetDocumentType() == DOCUMENT_TYPE_IMPRESS;
1157cdf0e10cSrcweir         sal_uInt16 nStringId;
1158cdf0e10cSrcweir         if (mbDirectionIsForward)
1159cdf0e10cSrcweir             nStringId = bImpress
1160cdf0e10cSrcweir                 ? STR_SAR_WRAP_FORWARD
1161cdf0e10cSrcweir                 : STR_SAR_WRAP_FORWARD_DRAW;
1162cdf0e10cSrcweir         else
1163cdf0e10cSrcweir             nStringId = bImpress
1164cdf0e10cSrcweir                 ? STR_SAR_WRAP_BACKWARD
1165cdf0e10cSrcweir                 : STR_SAR_WRAP_BACKWARD_DRAW;
1166cdf0e10cSrcweir 
1167cdf0e10cSrcweir         // Pop up question box that asks the user whether to wrap arround.
1168cdf0e10cSrcweir         // The dialog is made modal with respect to the whole application.
1169cdf0e10cSrcweir         QueryBox aQuestionBox (
1170cdf0e10cSrcweir             NULL,
1171cdf0e10cSrcweir             WB_YES_NO | WB_DEF_YES,
1172cdf0e10cSrcweir             String(SdResId(nStringId)));
1173cdf0e10cSrcweir         aQuestionBox.SetImage (QueryBox::GetStandardImage());
1174cdf0e10cSrcweir         sal_uInt16 nBoxResult = ShowModalMessageBox(aQuestionBox);
1175cdf0e10cSrcweir         bDoWrapArround = (nBoxResult == BUTTONID_YES);
1176cdf0e10cSrcweir     }
1177cdf0e10cSrcweir 
1178cdf0e10cSrcweir     return bDoWrapArround;
1179cdf0e10cSrcweir }
1180cdf0e10cSrcweir 
1181cdf0e10cSrcweir 
1182cdf0e10cSrcweir 
1183cdf0e10cSrcweir 
1184cdf0e10cSrcweir bool Outliner::IsValidTextObject (const ::sd::outliner::IteratorPosition& rPosition)
1185cdf0e10cSrcweir {
1186cdf0e10cSrcweir     SdrTextObj* pObject = dynamic_cast< SdrTextObj* >( rPosition.mxObject.get() );
1187cdf0e10cSrcweir     return (pObject != NULL) && pObject->HasText() && ! pObject->IsEmptyPresObj();
1188cdf0e10cSrcweir }
1189cdf0e10cSrcweir 
1190cdf0e10cSrcweir 
1191cdf0e10cSrcweir 
1192cdf0e10cSrcweir 
1193cdf0e10cSrcweir void Outliner::PutTextIntoOutliner()
1194cdf0e10cSrcweir {
1195cdf0e10cSrcweir     mpTextObj = dynamic_cast<SdrTextObj*>( mpObj );
1196cdf0e10cSrcweir     if ( mpTextObj && mpTextObj->HasText() && !mpTextObj->IsEmptyPresObj() )
1197cdf0e10cSrcweir     {
1198cdf0e10cSrcweir         SdrText* pText = mpTextObj->getText( mnText );
1199cdf0e10cSrcweir         mpParaObj = pText ? pText->GetOutlinerParaObject() : NULL;
1200cdf0e10cSrcweir 
1201cdf0e10cSrcweir         if (mpParaObj != NULL)
1202cdf0e10cSrcweir         {
1203cdf0e10cSrcweir             SetText(*mpParaObj);
1204cdf0e10cSrcweir 
1205cdf0e10cSrcweir             ClearModifyFlag();
1206cdf0e10cSrcweir         }
1207cdf0e10cSrcweir     }
1208cdf0e10cSrcweir     else
1209cdf0e10cSrcweir     {
1210cdf0e10cSrcweir         mpTextObj = NULL;
1211cdf0e10cSrcweir     }
1212cdf0e10cSrcweir }
1213cdf0e10cSrcweir 
1214cdf0e10cSrcweir 
1215cdf0e10cSrcweir 
1216cdf0e10cSrcweir 
1217cdf0e10cSrcweir void Outliner::PrepareSpellCheck (void)
1218cdf0e10cSrcweir {
1219cdf0e10cSrcweir     EESpellState eState = HasSpellErrors();
1220cdf0e10cSrcweir     DBG_ASSERT(eState != EE_SPELL_NOSPELLER, "No SpellChecker");
1221cdf0e10cSrcweir 
1222cdf0e10cSrcweir     if (eState == EE_SPELL_NOLANGUAGE)
1223cdf0e10cSrcweir     {
1224cdf0e10cSrcweir         mbError = sal_True;
1225cdf0e10cSrcweir         mbEndOfSearch = sal_True;
1226cdf0e10cSrcweir         ErrorBox aErrorBox (NULL,
1227cdf0e10cSrcweir             WB_OK,
1228cdf0e10cSrcweir             String(SdResId(STR_NOLANGUAGE)));
1229cdf0e10cSrcweir         ShowModalMessageBox (aErrorBox);
1230cdf0e10cSrcweir     }
1231cdf0e10cSrcweir     else if (eState != EE_SPELL_OK)
1232cdf0e10cSrcweir     {
1233cdf0e10cSrcweir         // When spell checking we have to test whether we have processed the
1234cdf0e10cSrcweir         // whole document and have reached the start page again.
1235cdf0e10cSrcweir         if (meMode == SPELL)
1236cdf0e10cSrcweir         {
1237cdf0e10cSrcweir             if (maSearchStartPosition == ::sd::outliner::Iterator())
1238cdf0e10cSrcweir                 // Remember the position of the first text object so that we
1239cdf0e10cSrcweir                 // know when we have processed the whole document.
1240cdf0e10cSrcweir                 maSearchStartPosition = maObjectIterator;
1241cdf0e10cSrcweir             else if (maSearchStartPosition == maObjectIterator)
1242cdf0e10cSrcweir             {
1243cdf0e10cSrcweir                 mbEndOfSearch = true;
1244cdf0e10cSrcweir             }
1245cdf0e10cSrcweir         }
1246cdf0e10cSrcweir 
1247cdf0e10cSrcweir         EnterEditMode( sal_False );
1248cdf0e10cSrcweir     }
1249cdf0e10cSrcweir }
1250cdf0e10cSrcweir 
1251cdf0e10cSrcweir 
1252cdf0e10cSrcweir 
1253cdf0e10cSrcweir 
1254cdf0e10cSrcweir void Outliner::PrepareSearchAndReplace (void)
1255cdf0e10cSrcweir {
1256cdf0e10cSrcweir     if (HasText( *mpSearchItem ))
1257cdf0e10cSrcweir     {
1258cdf0e10cSrcweir         mbStringFound = true;
1259cdf0e10cSrcweir         mbMatchMayExist = true;
1260cdf0e10cSrcweir 
1261cdf0e10cSrcweir         EnterEditMode ();
1262cdf0e10cSrcweir 
1263cdf0e10cSrcweir         mpDrawDocument->GetDocSh()->SetWaitCursor( sal_False );
1264cdf0e10cSrcweir         // Start seach at the right end of the current object's text
1265cdf0e10cSrcweir         // depending on the search direction.
1266cdf0e10cSrcweir         OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
1267cdf0e10cSrcweir         if (pOutlinerView != NULL)
1268cdf0e10cSrcweir             pOutlinerView->SetSelection (GetSearchStartPosition ());
1269cdf0e10cSrcweir     }
1270cdf0e10cSrcweir }
1271cdf0e10cSrcweir 
1272cdf0e10cSrcweir 
1273cdf0e10cSrcweir 
1274cdf0e10cSrcweir 
1275cdf0e10cSrcweir void Outliner::SetViewMode (PageKind ePageKind)
1276cdf0e10cSrcweir {
1277967189efSMichael Stahl     ::boost::shared_ptr<ViewShell> pViewShell (mpWeakViewShell.lock());
1278cdf0e10cSrcweir     ::boost::shared_ptr<DrawViewShell> pDrawViewShell(
1279967189efSMichael Stahl         ::boost::dynamic_pointer_cast<DrawViewShell>(pViewShell));
1280cdf0e10cSrcweir     if (pDrawViewShell.get()!=NULL && ePageKind != pDrawViewShell->GetPageKind())
1281cdf0e10cSrcweir     {
1282cdf0e10cSrcweir         // Restore old edit mode.
1283cdf0e10cSrcweir         pDrawViewShell->ChangeEditMode(mpImpl->meOriginalEditMode, sal_False);
1284cdf0e10cSrcweir 
1285cdf0e10cSrcweir         SetStatusEventHdl(Link());
1286cdf0e10cSrcweir         ::rtl::OUString sViewURL;
1287cdf0e10cSrcweir         switch (ePageKind)
1288cdf0e10cSrcweir         {
1289cdf0e10cSrcweir             case PK_STANDARD:
1290cdf0e10cSrcweir             default:
1291cdf0e10cSrcweir                 sViewURL = framework::FrameworkHelper::msImpressViewURL;
1292cdf0e10cSrcweir                 break;
1293cdf0e10cSrcweir             case PK_NOTES:
1294cdf0e10cSrcweir                 sViewURL = framework::FrameworkHelper::msNotesViewURL;
1295cdf0e10cSrcweir                 break;
1296cdf0e10cSrcweir             case PK_HANDOUT:
1297cdf0e10cSrcweir                 sViewURL = framework::FrameworkHelper::msHandoutViewURL;
1298cdf0e10cSrcweir                 break;
1299cdf0e10cSrcweir         }
1300cdf0e10cSrcweir         // The text object iterator is destroyed when the shells are
1301cdf0e10cSrcweir         // switched but we need it so save it and restore it afterwards.
1302cdf0e10cSrcweir         ::sd::outliner::Iterator aIterator (maObjectIterator);
1303cdf0e10cSrcweir         bool bMatchMayExist = mbMatchMayExist;
1304cdf0e10cSrcweir 
1305967189efSMichael Stahl         ViewShellBase& rBase = pViewShell->GetViewShellBase();
1306cdf0e10cSrcweir         SetViewShell(::boost::shared_ptr<ViewShell>());
1307cdf0e10cSrcweir         framework::FrameworkHelper::Instance(rBase)->RequestView(
1308cdf0e10cSrcweir             sViewURL,
1309cdf0e10cSrcweir             framework::FrameworkHelper::msCenterPaneURL);
1310cdf0e10cSrcweir 
1311cdf0e10cSrcweir         // Force (well, request) a synchronous update of the configuration.
1312cdf0e10cSrcweir         // In a better world we would handle the asynchronous view update
1313cdf0e10cSrcweir         // instead.  But that would involve major restucturing of the
1314cdf0e10cSrcweir         // Outliner code.
1315cdf0e10cSrcweir         framework::FrameworkHelper::Instance(rBase)->RequestSynchronousUpdate();
1316cdf0e10cSrcweir         SetViewShell(rBase.GetMainViewShell());
1317cdf0e10cSrcweir 
1318cdf0e10cSrcweir         // Switching to another view shell has intermediatly called
1319cdf0e10cSrcweir         // EndSpelling().  A PrepareSpelling() is pending, so call that now.
1320cdf0e10cSrcweir         PrepareSpelling();
1321cdf0e10cSrcweir 
1322cdf0e10cSrcweir         // Update the number of pages so that
1323cdf0e10cSrcweir         // <member>DetectChange()</member> has the correct value to compare
1324cdf0e10cSrcweir         // to.
1325cdf0e10cSrcweir         mnPageCount = mpDrawDocument->GetSdPageCount(ePageKind);
1326cdf0e10cSrcweir 
1327cdf0e10cSrcweir         maObjectIterator = aIterator;
1328cdf0e10cSrcweir         mbMatchMayExist = bMatchMayExist;
1329cdf0e10cSrcweir 
1330cdf0e10cSrcweir         // Save edit mode so that it can be restored when switching the view
1331cdf0e10cSrcweir         // shell again.
1332967189efSMichael Stahl         pDrawViewShell = ::boost::dynamic_pointer_cast<DrawViewShell>(pViewShell);
1333cdf0e10cSrcweir         OSL_ASSERT(pDrawViewShell.get()!=NULL);
1334cdf0e10cSrcweir         if (pDrawViewShell.get() != NULL)
1335cdf0e10cSrcweir             mpImpl->meOriginalEditMode = pDrawViewShell->GetEditMode();
1336cdf0e10cSrcweir     }
1337cdf0e10cSrcweir }
1338cdf0e10cSrcweir 
1339cdf0e10cSrcweir 
1340cdf0e10cSrcweir 
1341cdf0e10cSrcweir 
1342cdf0e10cSrcweir void Outliner::SetPage (EditMode eEditMode, sal_uInt16 nPageIndex)
1343cdf0e10cSrcweir {
1344cdf0e10cSrcweir     if ( ! mbRestrictSearchToSelection)
1345cdf0e10cSrcweir     {
1346967189efSMichael Stahl         ::boost::shared_ptr<ViewShell> pViewShell (mpWeakViewShell.lock());
1347cdf0e10cSrcweir         ::boost::shared_ptr<DrawViewShell> pDrawViewShell(
1348967189efSMichael Stahl             ::boost::dynamic_pointer_cast<DrawViewShell>(pViewShell));
1349cdf0e10cSrcweir         OSL_ASSERT(pDrawViewShell.get()!=NULL);
1350cdf0e10cSrcweir         if (pDrawViewShell.get() != NULL)
1351cdf0e10cSrcweir         {
1352cdf0e10cSrcweir             pDrawViewShell->ChangeEditMode(eEditMode, sal_False);
1353cdf0e10cSrcweir             pDrawViewShell->SwitchPage(nPageIndex);
1354cdf0e10cSrcweir         }
1355cdf0e10cSrcweir     }
1356cdf0e10cSrcweir }
1357cdf0e10cSrcweir 
1358cdf0e10cSrcweir 
1359cdf0e10cSrcweir 
1360cdf0e10cSrcweir 
1361cdf0e10cSrcweir void Outliner::EnterEditMode (sal_Bool bGrabFocus)
1362cdf0e10cSrcweir {
1363cdf0e10cSrcweir     OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
1364967189efSMichael Stahl     if (pOutlinerView != NULL)
1365cdf0e10cSrcweir     {
1366cdf0e10cSrcweir         pOutlinerView->SetOutputArea( Rectangle( Point(), Size(1, 1)));
1367cdf0e10cSrcweir         SetPaperSize( mpTextObj->GetLogicRect().GetSize() );
1368cdf0e10cSrcweir         SdrPageView* pPV = mpView->GetSdrPageView();
1369cdf0e10cSrcweir 
1370cdf0e10cSrcweir         // Make FuText the current function.
1371cdf0e10cSrcweir         SfxUInt16Item aItem (SID_TEXTEDIT, 1);
1372967189efSMichael Stahl         ::boost::shared_ptr<ViewShell> pViewShell (mpWeakViewShell.lock());
1373967189efSMichael Stahl         pViewShell->GetDispatcher()->
1374cdf0e10cSrcweir             Execute(SID_TEXTEDIT, SFX_CALLMODE_SYNCHRON |
1375cdf0e10cSrcweir                 SFX_CALLMODE_RECORD, &aItem, 0L);
1376cdf0e10cSrcweir 
1377cdf0e10cSrcweir         // To be consistent with the usual behaviour in the Office the text
1378cdf0e10cSrcweir         // object that is put into edit mode would have also to be selected.
1379cdf0e10cSrcweir         // Starting the text edit mode is not enough so we do it here by
1380cdf0e10cSrcweir         // hand.
1381cdf0e10cSrcweir         mbExpectingSelectionChangeEvent = true;
1382cdf0e10cSrcweir         mpView->UnmarkAllObj (pPV);
1383cdf0e10cSrcweir         mpView->MarkObj (mpTextObj, pPV);
1384cdf0e10cSrcweir 
1385cdf0e10cSrcweir         if( mpTextObj )
1386cdf0e10cSrcweir             mpTextObj->setActiveText( mnText );
1387cdf0e10cSrcweir 
1388cdf0e10cSrcweir         // Turn on the edit mode for the text object.
1389cdf0e10cSrcweir         mpView->SdrBeginTextEdit(mpTextObj, pPV, mpWindow, sal_True, this, pOutlinerView, sal_True, sal_True, bGrabFocus);
1390cdf0e10cSrcweir 
1391cdf0e10cSrcweir         SetUpdateMode(sal_True);
1392cdf0e10cSrcweir         mbFoundObject = sal_True;
1393cdf0e10cSrcweir     }
1394cdf0e10cSrcweir }
1395cdf0e10cSrcweir 
1396cdf0e10cSrcweir 
1397cdf0e10cSrcweir 
1398cdf0e10cSrcweir 
1399cdf0e10cSrcweir /*************************************************************************
1400cdf0e10cSrcweir |*
1401cdf0e10cSrcweir |* SpellChecker: Error-LinkHdl
1402cdf0e10cSrcweir |*
1403cdf0e10cSrcweir \************************************************************************/
1404cdf0e10cSrcweir 
1405cdf0e10cSrcweir IMPL_LINK_INLINE_START( Outliner, SpellError, void *, nLang )
1406cdf0e10cSrcweir {
1407cdf0e10cSrcweir     mbError = true;
1408cdf0e10cSrcweir     String aError( SvtLanguageTable::GetLanguageString( (LanguageType)(sal_uLong)nLang ) );
1409cdf0e10cSrcweir     ErrorHandler::HandleError(* new StringErrorInfo(
1410cdf0e10cSrcweir                                 ERRCODE_SVX_LINGU_LANGUAGENOTEXISTS, aError) );
1411cdf0e10cSrcweir     return 0;
1412cdf0e10cSrcweir }
1413cdf0e10cSrcweir IMPL_LINK_INLINE_END( Outliner, SpellError, void *, nLang )
1414cdf0e10cSrcweir 
1415cdf0e10cSrcweir 
1416cdf0e10cSrcweir 
1417cdf0e10cSrcweir 
1418cdf0e10cSrcweir ESelection Outliner::GetSearchStartPosition (void)
1419cdf0e10cSrcweir {
1420cdf0e10cSrcweir     ESelection aPosition;
1421cdf0e10cSrcweir     if (mbDirectionIsForward)
1422cdf0e10cSrcweir     {
1423cdf0e10cSrcweir         // The default constructor uses the beginning of the text as default.
1424cdf0e10cSrcweir         aPosition = ESelection ();
1425cdf0e10cSrcweir     }
1426cdf0e10cSrcweir     else
1427cdf0e10cSrcweir     {
1428cdf0e10cSrcweir         // Retrieve the position after the last character in the last
1429cdf0e10cSrcweir         // paragraph.
1430cdf0e10cSrcweir         sal_uInt16 nParagraphCount = static_cast<sal_uInt16>(GetParagraphCount());
1431cdf0e10cSrcweir         if (nParagraphCount == 0)
1432cdf0e10cSrcweir             aPosition = ESelection();
1433cdf0e10cSrcweir         else
1434cdf0e10cSrcweir         {
1435cdf0e10cSrcweir             xub_StrLen nLastParagraphLength = GetEditEngine().GetTextLen (
1436cdf0e10cSrcweir                 nParagraphCount-1);
1437cdf0e10cSrcweir             aPosition = ESelection (nParagraphCount-1, nLastParagraphLength);
1438cdf0e10cSrcweir         }
1439cdf0e10cSrcweir     }
1440cdf0e10cSrcweir 
1441cdf0e10cSrcweir     return aPosition;
1442cdf0e10cSrcweir }
1443cdf0e10cSrcweir 
1444cdf0e10cSrcweir 
1445cdf0e10cSrcweir 
1446cdf0e10cSrcweir 
1447cdf0e10cSrcweir bool Outliner::HasNoPreviousMatch (void)
1448cdf0e10cSrcweir {
1449cdf0e10cSrcweir     OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
1450cdf0e10cSrcweir 
1451cdf0e10cSrcweir     DBG_ASSERT (pOutlinerView!=NULL, "outline view in Outliner::HasNoPreviousMatch is NULL");
1452cdf0e10cSrcweir 
1453cdf0e10cSrcweir     // Detect whether the cursor stands at the beginning
1454cdf0e10cSrcweir     // resp. at the end of the text.
1455cdf0e10cSrcweir     return pOutlinerView->GetSelection().IsEqual(GetSearchStartPosition ()) == sal_True;
1456cdf0e10cSrcweir }
1457cdf0e10cSrcweir 
1458cdf0e10cSrcweir 
1459cdf0e10cSrcweir 
1460cdf0e10cSrcweir 
1461cdf0e10cSrcweir bool Outliner::HandleFailedSearch (void)
1462cdf0e10cSrcweir {
1463cdf0e10cSrcweir     bool bContinueSearch = false;
1464cdf0e10cSrcweir 
1465cdf0e10cSrcweir     OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
1466cdf0e10cSrcweir     if (pOutlinerView != NULL && mpSearchItem != NULL)
1467cdf0e10cSrcweir     {
1468cdf0e10cSrcweir         // Detect whether there is/may be a prior match.  If there is then
1469cdf0e10cSrcweir         // ask the user whether to wrap arround.  Otherwise tell the user
1470cdf0e10cSrcweir         // that there is no match.
1471cdf0e10cSrcweir         if (HasNoPreviousMatch ())
1472cdf0e10cSrcweir         {
1473cdf0e10cSrcweir             // No match found in the whole presentation.  Tell the user.
1474cdf0e10cSrcweir             InfoBox aInfoBox (NULL,
1475cdf0e10cSrcweir                 String(SdResId(STR_SAR_NOT_FOUND)));
1476cdf0e10cSrcweir             ShowModalMessageBox (aInfoBox);
1477cdf0e10cSrcweir         }
1478cdf0e10cSrcweir 
1479cdf0e10cSrcweir         else
1480cdf0e10cSrcweir         {
1481cdf0e10cSrcweir             // No further matches found.  Ask the user whether to wrap
1482cdf0e10cSrcweir             // arround and start again.
1483cdf0e10cSrcweir             bContinueSearch = ShowWrapArroundDialog ();
1484cdf0e10cSrcweir         }
1485cdf0e10cSrcweir     }
1486cdf0e10cSrcweir 
1487cdf0e10cSrcweir     return bContinueSearch;
1488cdf0e10cSrcweir }
1489cdf0e10cSrcweir 
1490cdf0e10cSrcweir 
1491cdf0e10cSrcweir SdrObject* Outliner::SetObject (
1492cdf0e10cSrcweir     const ::sd::outliner::IteratorPosition& rPosition)
1493cdf0e10cSrcweir {
1494cdf0e10cSrcweir     SetViewMode (rPosition.mePageKind);
1495cdf0e10cSrcweir     SetPage (rPosition.meEditMode, (sal_uInt16)rPosition.mnPageIndex);
1496cdf0e10cSrcweir     mnText = rPosition.mnText;
1497cdf0e10cSrcweir     return rPosition.mxObject.get();
1498cdf0e10cSrcweir }
1499cdf0e10cSrcweir 
1500cdf0e10cSrcweir 
1501cdf0e10cSrcweir 
1502cdf0e10cSrcweir 
1503cdf0e10cSrcweir void Outliner::SetViewShell (const ::boost::shared_ptr<ViewShell>& rpViewShell)
1504cdf0e10cSrcweir {
1505967189efSMichael Stahl     ::boost::shared_ptr<ViewShell> pViewShell (mpWeakViewShell.lock());
1506967189efSMichael Stahl     if (pViewShell != rpViewShell)
1507cdf0e10cSrcweir     {
1508cdf0e10cSrcweir         // Set the new view shell.
1509967189efSMichael Stahl         mpWeakViewShell = rpViewShell;
1510cdf0e10cSrcweir         // When the outline view is not owned by us then we have to clear
1511cdf0e10cSrcweir         // that pointer so that the current one for the new view shell will
1512cdf0e10cSrcweir         // be used (in ProvideOutlinerView).
1513cdf0e10cSrcweir         //        if ( ! mbOwnOutlineView)
1514cdf0e10cSrcweir         //            mpOutlineView = NULL;
1515967189efSMichael Stahl         if (rpViewShell)
1516cdf0e10cSrcweir         {
1517967189efSMichael Stahl             mpView = rpViewShell->GetView();
1518cdf0e10cSrcweir 
1519967189efSMichael Stahl             mpWindow = rpViewShell->GetActiveWindow();
1520cdf0e10cSrcweir 
1521967189efSMichael Stahl             mpImpl->ProvideOutlinerView(*this, rpViewShell, mpWindow);
1522cdf0e10cSrcweir             OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
1523cdf0e10cSrcweir             if (pOutlinerView != NULL)
1524cdf0e10cSrcweir                 pOutlinerView->SetWindow(mpWindow);
1525cdf0e10cSrcweir         }
1526cdf0e10cSrcweir         else
1527cdf0e10cSrcweir         {
1528cdf0e10cSrcweir             mpView = NULL;
1529cdf0e10cSrcweir             mpWindow = NULL;
1530cdf0e10cSrcweir         }
1531cdf0e10cSrcweir     }
1532cdf0e10cSrcweir }
1533cdf0e10cSrcweir 
1534cdf0e10cSrcweir 
1535cdf0e10cSrcweir 
1536cdf0e10cSrcweir 
1537cdf0e10cSrcweir void Outliner::HandleChangedSelection (void)
1538cdf0e10cSrcweir {
1539cdf0e10cSrcweir     maMarkListCopy.clear();
1540cdf0e10cSrcweir     mbRestrictSearchToSelection = (mpView->AreObjectsMarked()==sal_True);
1541cdf0e10cSrcweir     if (mbRestrictSearchToSelection)
1542cdf0e10cSrcweir     {
1543cdf0e10cSrcweir         // Make a copy of the current mark list.
1544cdf0e10cSrcweir         const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
1545cdf0e10cSrcweir         sal_uLong nCount = rMarkList.GetMarkCount();
1546cdf0e10cSrcweir         if (nCount > 0)
1547cdf0e10cSrcweir         {
1548cdf0e10cSrcweir             maMarkListCopy.clear();
1549cdf0e10cSrcweir             maMarkListCopy.reserve (nCount);
1550cdf0e10cSrcweir             for (sal_uLong i=0; i<nCount; i++)
1551cdf0e10cSrcweir                 maMarkListCopy.push_back (rMarkList.GetMark(i)->GetMarkedSdrObj ());
1552cdf0e10cSrcweir         }
1553cdf0e10cSrcweir         else
1554cdf0e10cSrcweir             // No marked object.  Is this case possible?
1555cdf0e10cSrcweir             mbRestrictSearchToSelection = false;
1556cdf0e10cSrcweir     }
1557cdf0e10cSrcweir }
1558cdf0e10cSrcweir 
1559cdf0e10cSrcweir 
1560cdf0e10cSrcweir 
1561cdf0e10cSrcweir 
1562cdf0e10cSrcweir 
1563cdf0e10cSrcweir void Outliner::StartConversion( sal_Int16 nSourceLanguage,  sal_Int16 nTargetLanguage,
1564cdf0e10cSrcweir         const Font *pTargetFont, sal_Int32 nOptions, sal_Bool bIsInteractive )
1565cdf0e10cSrcweir {
1566967189efSMichael Stahl     ::boost::shared_ptr<ViewShell> pViewShell (mpWeakViewShell.lock());
1567967189efSMichael Stahl     sal_Bool bMultiDoc = pViewShell->ISA(DrawViewShell);
1568cdf0e10cSrcweir 
1569cdf0e10cSrcweir     meMode = TEXT_CONVERSION;
1570cdf0e10cSrcweir     mbDirectionIsForward = true;
1571cdf0e10cSrcweir     mpSearchItem = NULL;
1572cdf0e10cSrcweir     mnConversionLanguage = nSourceLanguage;
1573cdf0e10cSrcweir 
1574cdf0e10cSrcweir     BeginConversion();
1575cdf0e10cSrcweir 
1576cdf0e10cSrcweir     OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
1577cdf0e10cSrcweir     if (pOutlinerView != NULL)
1578cdf0e10cSrcweir     {
1579cdf0e10cSrcweir         pOutlinerView->StartTextConversion(
1580cdf0e10cSrcweir             nSourceLanguage,
1581cdf0e10cSrcweir             nTargetLanguage,
1582cdf0e10cSrcweir             pTargetFont,
1583cdf0e10cSrcweir             nOptions,
1584cdf0e10cSrcweir             bIsInteractive,
1585cdf0e10cSrcweir             bMultiDoc);
1586cdf0e10cSrcweir     }
1587cdf0e10cSrcweir 
1588cdf0e10cSrcweir     EndConversion();
1589cdf0e10cSrcweir }
1590cdf0e10cSrcweir 
1591cdf0e10cSrcweir 
1592cdf0e10cSrcweir 
1593cdf0e10cSrcweir 
1594cdf0e10cSrcweir /** Prepare to do a text conversion on the current text object. This
1595cdf0e10cSrcweir     includes putting it into edit mode.
1596cdf0e10cSrcweir */
1597cdf0e10cSrcweir void Outliner::PrepareConversion (void)
1598cdf0e10cSrcweir {
1599cdf0e10cSrcweir     SetUpdateMode(sal_True);
1600cdf0e10cSrcweir     if( HasConvertibleTextPortion( mnConversionLanguage ) )
1601cdf0e10cSrcweir     {
1602cdf0e10cSrcweir         SetUpdateMode(sal_False);
1603cdf0e10cSrcweir         mbStringFound = sal_True;
1604cdf0e10cSrcweir         mbMatchMayExist = sal_True;
1605cdf0e10cSrcweir 
1606cdf0e10cSrcweir         EnterEditMode ();
1607cdf0e10cSrcweir 
1608cdf0e10cSrcweir         mpDrawDocument->GetDocSh()->SetWaitCursor( sal_False );
1609cdf0e10cSrcweir         // Start seach at the right end of the current object's text
1610cdf0e10cSrcweir         // depending on the search direction.
1611cdf0e10cSrcweir //      mpOutlineView->SetSelection (GetSearchStartPosition ());
1612cdf0e10cSrcweir     }
1613cdf0e10cSrcweir     else
1614cdf0e10cSrcweir     {
1615cdf0e10cSrcweir         SetUpdateMode(sal_False);
1616cdf0e10cSrcweir     }
1617cdf0e10cSrcweir }
1618cdf0e10cSrcweir 
1619cdf0e10cSrcweir 
1620cdf0e10cSrcweir 
1621cdf0e10cSrcweir 
1622cdf0e10cSrcweir void Outliner::BeginConversion (void)
1623cdf0e10cSrcweir {
1624cdf0e10cSrcweir     SetRefDevice( SD_MOD()->GetRefDevice( *mpDrawDocument->GetDocSh() ) );
1625cdf0e10cSrcweir 
1626cdf0e10cSrcweir     ViewShellBase* pBase = PTR_CAST(ViewShellBase, SfxViewShell::Current());
1627cdf0e10cSrcweir     if (pBase != NULL)
1628cdf0e10cSrcweir         SetViewShell (pBase->GetMainViewShell());
1629cdf0e10cSrcweir 
1630967189efSMichael Stahl     ::boost::shared_ptr<ViewShell> pViewShell (mpWeakViewShell.lock());
1631967189efSMichael Stahl     if (pViewShell)
1632cdf0e10cSrcweir     {
1633cdf0e10cSrcweir         mbStringFound = sal_False;
1634cdf0e10cSrcweir 
1635cdf0e10cSrcweir         // Supposed that we are not located at the very beginning/end of the
1636cdf0e10cSrcweir         // document then there may be a match in the document prior/after
1637cdf0e10cSrcweir         // the current position.
1638cdf0e10cSrcweir         mbMatchMayExist = sal_True;
1639cdf0e10cSrcweir 
1640cdf0e10cSrcweir         maObjectIterator = ::sd::outliner::Iterator();
1641cdf0e10cSrcweir         maSearchStartPosition = ::sd::outliner::Iterator();
1642cdf0e10cSrcweir         RememberStartPosition();
1643cdf0e10cSrcweir 
1644967189efSMichael Stahl         mpImpl->ProvideOutlinerView(*this, pViewShell, mpWindow);
1645cdf0e10cSrcweir 
1646cdf0e10cSrcweir         HandleChangedSelection ();
1647cdf0e10cSrcweir     }
1648cdf0e10cSrcweir     ClearModifyFlag();
1649cdf0e10cSrcweir }
1650cdf0e10cSrcweir 
1651cdf0e10cSrcweir 
1652cdf0e10cSrcweir 
1653cdf0e10cSrcweir 
1654cdf0e10cSrcweir void Outliner::EndConversion()
1655cdf0e10cSrcweir {
1656cdf0e10cSrcweir     EndSpelling();
1657cdf0e10cSrcweir }
1658cdf0e10cSrcweir 
1659cdf0e10cSrcweir 
1660cdf0e10cSrcweir 
1661cdf0e10cSrcweir 
1662cdf0e10cSrcweir sal_Bool Outliner::ConvertNextDocument()
1663cdf0e10cSrcweir {
1664967189efSMichael Stahl     ::boost::shared_ptr<ViewShell> pViewShell (mpWeakViewShell.lock());
1665967189efSMichael Stahl     if (pViewShell && pViewShell->ISA(OutlineViewShell) )
1666cdf0e10cSrcweir         return false;
1667cdf0e10cSrcweir 
1668cdf0e10cSrcweir     mpDrawDocument->GetDocSh()->SetWaitCursor( sal_True );
1669cdf0e10cSrcweir 
1670cdf0e10cSrcweir     Initialize ( true );
1671cdf0e10cSrcweir 
1672cdf0e10cSrcweir     OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
1673cdf0e10cSrcweir     if (pOutlinerView != NULL)
1674cdf0e10cSrcweir     {
1675967189efSMichael Stahl         mpWindow = pViewShell->GetActiveWindow();
1676cdf0e10cSrcweir         pOutlinerView->SetWindow(mpWindow);
1677cdf0e10cSrcweir     }
1678cdf0e10cSrcweir     ProvideNextTextObject ();
1679cdf0e10cSrcweir 
1680cdf0e10cSrcweir     mpDrawDocument->GetDocSh()->SetWaitCursor( sal_False );
1681cdf0e10cSrcweir     ClearModifyFlag();
1682cdf0e10cSrcweir 
1683cdf0e10cSrcweir     // for text conversion we automaticly wrap around one
1684cdf0e10cSrcweir     // time and stop at the start shape
1685cdf0e10cSrcweir     if( mpFirstObj )
1686cdf0e10cSrcweir     {
1687cdf0e10cSrcweir         if( (mnText == 0) && (mpFirstObj == mpObj) )
1688cdf0e10cSrcweir             return false;
1689cdf0e10cSrcweir     }
1690cdf0e10cSrcweir     else
1691cdf0e10cSrcweir     {
1692cdf0e10cSrcweir         mpFirstObj = mpObj;
1693cdf0e10cSrcweir     }
1694cdf0e10cSrcweir 
1695cdf0e10cSrcweir     return !mbEndOfSearch;
1696cdf0e10cSrcweir }
1697cdf0e10cSrcweir 
1698cdf0e10cSrcweir 
1699cdf0e10cSrcweir 
1700cdf0e10cSrcweir 
1701cdf0e10cSrcweir sal_uInt16 Outliner::ShowModalMessageBox (Dialog& rMessageBox)
1702cdf0e10cSrcweir {
1703cdf0e10cSrcweir     // We assume that the parent of the given messge box is NULL, i.e. it is
1704cdf0e10cSrcweir     // modal with respect to the top application window. However, this
1705cdf0e10cSrcweir     // does not affect the search dialog.  Therefore we have to lock it here
1706cdf0e10cSrcweir     // while the message box is being shown.  We also have to take into
1707cdf0e10cSrcweir     // account that we are called during a spell check and the search dialog
1708cdf0e10cSrcweir     // is not available.
1709cdf0e10cSrcweir     ::Window* pSearchDialog = NULL;
1710cdf0e10cSrcweir     SfxChildWindow* pChildWindow = NULL;
1711cdf0e10cSrcweir     switch (meMode)
1712cdf0e10cSrcweir     {
1713cdf0e10cSrcweir         case SEARCH:
1714cdf0e10cSrcweir             pChildWindow = SfxViewFrame::Current()->GetChildWindow(
1715cdf0e10cSrcweir                 SvxSearchDialogWrapper::GetChildWindowId());
1716cdf0e10cSrcweir             break;
1717cdf0e10cSrcweir 
1718cdf0e10cSrcweir         case SPELL:
1719cdf0e10cSrcweir             pChildWindow = SfxViewFrame::Current()->GetChildWindow(
1720cdf0e10cSrcweir                 SpellDialogChildWindow::GetChildWindowId());
1721cdf0e10cSrcweir             break;
1722cdf0e10cSrcweir 
1723cdf0e10cSrcweir         case TEXT_CONVERSION:
1724cdf0e10cSrcweir             // There should no messages boxes be displayed while doing the
1725cdf0e10cSrcweir             // hangul hanja conversion.
1726cdf0e10cSrcweir             break;
1727cdf0e10cSrcweir     }
1728cdf0e10cSrcweir 
1729cdf0e10cSrcweir     if (pChildWindow != NULL)
1730cdf0e10cSrcweir         pSearchDialog = pChildWindow->GetWindow();
1731cdf0e10cSrcweir     if (pSearchDialog != NULL)
1732cdf0e10cSrcweir         pSearchDialog->EnableInput(sal_False,sal_True);
1733cdf0e10cSrcweir 
1734cdf0e10cSrcweir     sal_uInt16 nResult = rMessageBox.Execute();
1735cdf0e10cSrcweir 
1736cdf0e10cSrcweir     // Unlock the search dialog.
1737cdf0e10cSrcweir     if (pSearchDialog != NULL)
1738cdf0e10cSrcweir         pSearchDialog->EnableInput(sal_True,sal_True);
1739cdf0e10cSrcweir 
1740cdf0e10cSrcweir     return nResult;
1741cdf0e10cSrcweir }
1742cdf0e10cSrcweir 
1743cdf0e10cSrcweir 
1744cdf0e10cSrcweir 
1745cdf0e10cSrcweir 
1746cdf0e10cSrcweir //===== Outliner::Implementation ==============================================
1747cdf0e10cSrcweir 
1748cdf0e10cSrcweir Outliner::Implementation::Implementation (void)
1749cdf0e10cSrcweir     : meOriginalEditMode(EM_PAGE),
1750cdf0e10cSrcweir       mbOwnOutlineView(false),
1751cdf0e10cSrcweir       mpOutlineView(NULL)
1752cdf0e10cSrcweir {
1753cdf0e10cSrcweir }
1754cdf0e10cSrcweir 
1755cdf0e10cSrcweir 
1756cdf0e10cSrcweir 
1757cdf0e10cSrcweir 
1758cdf0e10cSrcweir Outliner::Implementation::~Implementation (void)
1759cdf0e10cSrcweir {
1760cdf0e10cSrcweir     if (mbOwnOutlineView && mpOutlineView!=NULL)
1761cdf0e10cSrcweir     {
1762cdf0e10cSrcweir         mpOutlineView->SetWindow(NULL);
1763cdf0e10cSrcweir         delete mpOutlineView;
1764cdf0e10cSrcweir         mpOutlineView = NULL;
1765cdf0e10cSrcweir     }
1766cdf0e10cSrcweir }
1767cdf0e10cSrcweir 
1768cdf0e10cSrcweir 
1769cdf0e10cSrcweir 
1770cdf0e10cSrcweir 
1771cdf0e10cSrcweir OutlinerView* Outliner::Implementation::GetOutlinerView ()
1772cdf0e10cSrcweir {
1773cdf0e10cSrcweir     return mpOutlineView;
1774cdf0e10cSrcweir }
1775cdf0e10cSrcweir 
1776cdf0e10cSrcweir 
1777cdf0e10cSrcweir 
1778cdf0e10cSrcweir 
1779cdf0e10cSrcweir /** We try to create a new OutlinerView only when there is none available,
1780cdf0e10cSrcweir     either from an OutlinerViewShell or a previous call to
1781cdf0e10cSrcweir     ProvideOutlinerView().  This is necessary to support the spell checker
1782cdf0e10cSrcweir     which can not cope with exchanging the OutlinerView.
1783cdf0e10cSrcweir */
1784cdf0e10cSrcweir void Outliner::Implementation::ProvideOutlinerView (
1785cdf0e10cSrcweir     Outliner& rOutliner,
1786cdf0e10cSrcweir     const ::boost::shared_ptr<ViewShell>& rpViewShell,
1787cdf0e10cSrcweir     ::Window* pWindow)
1788cdf0e10cSrcweir {
1789cdf0e10cSrcweir     if (rpViewShell.get() != NULL)
1790cdf0e10cSrcweir     {
1791cdf0e10cSrcweir         switch (rpViewShell->GetShellType())
1792cdf0e10cSrcweir         {
1793cdf0e10cSrcweir             case ViewShell::ST_DRAW:
1794cdf0e10cSrcweir             case ViewShell::ST_IMPRESS:
1795cdf0e10cSrcweir             case ViewShell::ST_NOTES:
1796cdf0e10cSrcweir             case ViewShell::ST_HANDOUT:
1797cdf0e10cSrcweir             {
1798cdf0e10cSrcweir                 // Create a new outline view to do the search on.
1799cdf0e10cSrcweir                 bool bInsert = false;
1800cdf0e10cSrcweir                 if (mpOutlineView!=NULL && !mbOwnOutlineView)
1801cdf0e10cSrcweir                     mpOutlineView = NULL;
1802cdf0e10cSrcweir                 if (mpOutlineView == NULL)
1803cdf0e10cSrcweir                 {
1804cdf0e10cSrcweir                     mpOutlineView = new OutlinerView(&rOutliner, pWindow);
1805cdf0e10cSrcweir                     mbOwnOutlineView = true;
1806cdf0e10cSrcweir                     bInsert = true;
1807cdf0e10cSrcweir                 }
1808cdf0e10cSrcweir                 else
1809cdf0e10cSrcweir                     mpOutlineView->SetWindow(pWindow);
1810cdf0e10cSrcweir                 sal_uLong nStat = mpOutlineView->GetControlWord();
1811cdf0e10cSrcweir                 nStat &= ~EV_CNTRL_AUTOSCROLL;
1812cdf0e10cSrcweir                 mpOutlineView->SetControlWord(nStat);
1813cdf0e10cSrcweir                 if (bInsert)
1814cdf0e10cSrcweir                     rOutliner.InsertView( mpOutlineView );
1815cdf0e10cSrcweir                 rOutliner.SetUpdateMode(sal_False);
1816cdf0e10cSrcweir                 mpOutlineView->SetOutputArea (Rectangle (Point(), Size(1, 1)));
1817cdf0e10cSrcweir                 rOutliner.SetPaperSize( Size(1, 1) );
1818cdf0e10cSrcweir                 rOutliner.SetText( String(), rOutliner.GetParagraph( 0 ) );
1819cdf0e10cSrcweir 
1820cdf0e10cSrcweir                 meOriginalEditMode =
1821cdf0e10cSrcweir                     ::boost::static_pointer_cast<DrawViewShell>(rpViewShell)->GetEditMode();
1822cdf0e10cSrcweir             }
1823cdf0e10cSrcweir             break;
1824cdf0e10cSrcweir 
1825cdf0e10cSrcweir             case ViewShell::ST_OUTLINE:
1826cdf0e10cSrcweir             {
1827cdf0e10cSrcweir                 if (mpOutlineView!=NULL && mbOwnOutlineView)
1828cdf0e10cSrcweir                     delete mpOutlineView;
1829cdf0e10cSrcweir                 mpOutlineView = rOutliner.GetView(0);
1830cdf0e10cSrcweir                 mbOwnOutlineView = false;
1831cdf0e10cSrcweir             }
1832cdf0e10cSrcweir             break;
1833cdf0e10cSrcweir 
1834cdf0e10cSrcweir             default:
1835cdf0e10cSrcweir             case ViewShell::ST_NONE:
1836cdf0e10cSrcweir             case ViewShell::ST_PRESENTATION:
1837cdf0e10cSrcweir                 // Ignored
1838cdf0e10cSrcweir                 break;
1839cdf0e10cSrcweir         }
1840cdf0e10cSrcweir     }
1841cdf0e10cSrcweir }
1842cdf0e10cSrcweir 
1843cdf0e10cSrcweir 
1844cdf0e10cSrcweir 
1845cdf0e10cSrcweir 
1846cdf0e10cSrcweir void Outliner::Implementation::ReleaseOutlinerView (void)
1847cdf0e10cSrcweir {
1848cdf0e10cSrcweir     if (mbOwnOutlineView)
1849cdf0e10cSrcweir     {
1850cdf0e10cSrcweir         OutlinerView* pView = mpOutlineView;
1851cdf0e10cSrcweir         mpOutlineView = NULL;
1852cdf0e10cSrcweir         mbOwnOutlineView = false;
1853cdf0e10cSrcweir         if (pView != NULL)
1854cdf0e10cSrcweir         {
1855cdf0e10cSrcweir             pView->SetWindow(NULL);
1856cdf0e10cSrcweir             delete pView;
1857cdf0e10cSrcweir         }
1858cdf0e10cSrcweir     }
1859cdf0e10cSrcweir     else
1860cdf0e10cSrcweir     {
1861cdf0e10cSrcweir         mpOutlineView = NULL;
1862cdf0e10cSrcweir     }
1863cdf0e10cSrcweir }
1864cdf0e10cSrcweir 
1865cdf0e10cSrcweir } // end of namespace sd
1866