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