xref: /AOO41X/main/sw/source/core/edit/editsh.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sw.hxx"
30 
31 #include <hintids.hxx>
32 #include <tools/list.hxx>
33 #include <tools/urlobj.hxx>
34 #include <vcl/cmdevt.hxx>
35 #include <unotools/charclass.hxx>
36 #include <comphelper/processfactory.hxx>
37 #include <unotools/transliterationwrapper.hxx>
38 #include <swwait.hxx>
39 #include <fmtsrnd.hxx>
40 #include <fmtinfmt.hxx>
41 #include <txtinet.hxx>
42 #include <frmfmt.hxx>
43 #include <charfmt.hxx>
44 #include <doc.hxx>
45 #include <IDocumentUndoRedo.hxx>
46 #include <docary.hxx>
47 #include <editsh.hxx>
48 #include <frame.hxx>
49 #include <cntfrm.hxx>
50 #include <pam.hxx>
51 #include <ndtxt.hxx>			// fuer SwTxtNode
52 #include <grfatr.hxx>
53 #include <flyfrm.hxx>
54 #include <swtable.hxx>
55 #include <swundo.hxx> 			// UNDO_START, UNDO_END
56 #include <calc.hxx>
57 #include <edimp.hxx>
58 #include <ndgrf.hxx>
59 #include <ndole.hxx>
60 #include <txtfrm.hxx>
61 #include <rootfrm.hxx>
62 #include <extinput.hxx>
63 #include <crsskip.hxx>
64 #include <scriptinfo.hxx>
65 #include <unocrsrhelper.hxx>
66 #include <section.hxx>
67 #include <unochart.hxx>
68 #include <numrule.hxx>
69 #include <SwNodeNum.hxx>
70 #include <unocrsr.hxx>
71 #include <switerator.hxx>
72 
73 using namespace com::sun::star;
74 
75 
76 SV_IMPL_PTRARR(SwGetINetAttrs, SwGetINetAttr*)
77 
78 /******************************************************************************
79  *						void SwEditShell::Insert(char c)
80  ******************************************************************************/
81 
82 
83 void SwEditShell::Insert( sal_Unicode c, sal_Bool bOnlyCurrCrsr )
84 {
85 	StartAllAction();
86 	FOREACHPAM_START(this)
87 
88         const bool bSuccess = GetDoc()->InsertString(*PCURCRSR, c);
89         ASSERT( bSuccess, "Doc->Insert() failed." );
90         (void) bSuccess;
91 
92 		SaveTblBoxCntnt( PCURCRSR->GetPoint() );
93 		if( bOnlyCurrCrsr )
94 			break;
95 
96 	FOREACHPAM_END()
97 
98 	EndAllAction();
99 }
100 
101 
102 /******************************************************************************
103  *				  void SwEditShell::Insert(const String &rStr)
104  ******************************************************************************/
105 
106 
107 void SwEditShell::Insert2(const String &rStr, const bool bForceExpandHints )
108 {
109 	StartAllAction();
110 	{
111         const enum IDocumentContentOperations::InsertFlags nInsertFlags =
112             (bForceExpandHints)
113             ? static_cast<IDocumentContentOperations::InsertFlags>(
114                     IDocumentContentOperations::INS_FORCEHINTEXPAND |
115                     IDocumentContentOperations::INS_EMPTYEXPAND)
116             : IDocumentContentOperations::INS_EMPTYEXPAND;
117 
118 		SwPaM *_pStartCrsr = getShellCrsr( true ), *__pStartCrsr = _pStartCrsr;
119 		do {
120             //OPT: GetSystemCharSet
121             const bool bSuccess =
122                 GetDoc()->InsertString(*_pStartCrsr, rStr, nInsertFlags);
123             ASSERT( bSuccess, "Doc->Insert() failed." );
124             (void) bSuccess;
125 
126             SaveTblBoxCntnt( _pStartCrsr->GetPoint() );
127 
128 		} while( (_pStartCrsr=(SwPaM *)_pStartCrsr->GetNext()) != __pStartCrsr );
129 	}
130 
131     // calculate cursor bidi level
132     SwCursor* pTmpCrsr = _GetCrsr();
133     const sal_Bool bDoNotSetBidiLevel = ! pTmpCrsr ||
134                                 ( 0 != dynamic_cast<SwUnoCrsr*>(pTmpCrsr) );
135 
136     if ( ! bDoNotSetBidiLevel )
137     {
138         SwNode& rNode = pTmpCrsr->GetPoint()->nNode.GetNode();
139         if ( rNode.IsTxtNode() )
140         {
141             SwIndex& rIdx = pTmpCrsr->GetPoint()->nContent;
142             xub_StrLen nPos = rIdx.GetIndex();
143             xub_StrLen nPrevPos = nPos;
144             if ( nPrevPos )
145                 --nPrevPos;
146 
147             SwScriptInfo* pSI = SwScriptInfo::GetScriptInfo( ((SwTxtNode&)rNode),
148                                                               sal_True );
149 
150             sal_uInt8 nLevel = 0;
151             if ( ! pSI )
152             {
153                 // seems to be an empty paragraph.
154                 Point aPt;
155                 SwCntntFrm* pFrm =
156                         ((SwTxtNode&)rNode).getLayoutFrm( GetLayout(), &aPt, pTmpCrsr->GetPoint(),
157                                                     sal_False );
158 
159                 SwScriptInfo aScriptInfo;
160                 aScriptInfo.InitScriptInfo( (SwTxtNode&)rNode, pFrm->IsRightToLeft() );
161                 nLevel = aScriptInfo.DirType( nPrevPos );
162             }
163             else
164             {
165 				if ( STRING_LEN != pSI->GetInvalidity() )
166 	                pSI->InitScriptInfo( (SwTxtNode&)rNode );
167                 nLevel = pSI->DirType( nPrevPos );
168             }
169 
170             pTmpCrsr->SetCrsrBidiLevel( nLevel );
171         }
172     }
173 
174     SetInFrontOfLabel( sal_False ); // #i27615#
175 
176     EndAllAction();
177 }
178 
179 
180 /******************************************************************************
181  *				void SwEditShell::Overwrite(const String &rStr)
182  ******************************************************************************/
183 
184 
185 void SwEditShell::Overwrite(const String &rStr)
186 {
187 	StartAllAction();
188 	FOREACHPAM_START(this)
189         if( !GetDoc()->Overwrite(*PCURCRSR, rStr ) )
190         {
191 			ASSERT( sal_False, "Doc->Overwrite(Str) failed." )
192         }
193 		SaveTblBoxCntnt( PCURCRSR->GetPoint() );
194 	FOREACHPAM_END()
195 	EndAllAction();
196 }
197 
198 
199 /******************************************************************************
200  *						long SwEditShell::SplitNode()
201  ******************************************************************************/
202 
203 long SwEditShell::SplitNode( sal_Bool bAutoFormat, sal_Bool bCheckTableStart )
204 {
205 	StartAllAction();
206     GetDoc()->GetIDocumentUndoRedo().StartUndo(UNDO_EMPTY, NULL);
207 
208 	FOREACHPAM_START(this)
209 		// eine Tabellen Zelle wird jetzt zu einer normalen Textzelle!
210 		GetDoc()->ClearBoxNumAttrs( PCURCRSR->GetPoint()->nNode );
211 		GetDoc()->SplitNode( *PCURCRSR->GetPoint(), bCheckTableStart );
212 	FOREACHPAM_END()
213 
214     GetDoc()->GetIDocumentUndoRedo().EndUndo(UNDO_EMPTY, NULL);
215 
216 	if( bAutoFormat )
217 		AutoFmtBySplitNode();
218 
219 	ClearTblBoxCntnt();
220 
221 	EndAllAction();
222 	return(1L);
223 }
224 
225 /*-- 11.05.2004 09:41:20---------------------------------------------------
226 
227   -----------------------------------------------------------------------*/
228 sal_Bool SwEditShell::AppendTxtNode()
229 {
230     sal_Bool bRet = sal_False;
231     StartAllAction();
232     GetDoc()->GetIDocumentUndoRedo().StartUndo(UNDO_EMPTY, NULL);
233 
234     FOREACHPAM_START(this)
235         GetDoc()->ClearBoxNumAttrs( PCURCRSR->GetPoint()->nNode );
236         bRet = GetDoc()->AppendTxtNode( *PCURCRSR->GetPoint()) || bRet;
237     FOREACHPAM_END()
238 
239     GetDoc()->GetIDocumentUndoRedo().EndUndo(UNDO_EMPTY, NULL);
240 
241     ClearTblBoxCntnt();
242 
243     EndAllAction();
244     return bRet;
245 }
246 
247 /******************************************************************************
248  *		  liefert einen Pointer auf einen SwGrfNode; dieser wird von
249  *		  		GetGraphic() und GetGraphicSize() verwendet.
250  ******************************************************************************/
251 
252 
253 SwGrfNode * SwEditShell::_GetGrfNode() const
254 {
255 	SwGrfNode *pGrfNode = 0;
256 	SwPaM* pCrsr = GetCrsr();
257 	if( !pCrsr->HasMark() ||
258 		pCrsr->GetPoint()->nNode == pCrsr->GetMark()->nNode )
259 		pGrfNode = pCrsr->GetPoint()->nNode.GetNode().GetGrfNode();
260 
261 	return pGrfNode;
262 }
263 /******************************************************************************
264  * 		liefert Pointer auf eine Graphic, wenn CurCrsr->GetPoint() auf
265  * 			 einen SwGrfNode zeigt (und GetMark nicht gesetzt ist
266  * 					 oder auf die gleiche Graphic zeigt)
267  ******************************************************************************/
268 
269 // --> OD 2005-02-09 #119353# - robust
270 const Graphic* SwEditShell::GetGraphic( sal_Bool bWait ) const
271 {
272     SwGrfNode* pGrfNode = _GetGrfNode();
273     // --> OD 2005-02-09 #119353# - robust
274     const Graphic* pGrf( 0L );
275     if ( pGrfNode )
276     {
277         pGrf = &(pGrfNode->GetGrf());
278         // --> OD 2007-03-01 #i73788#
279         // no load of linked graphic, if its not needed now (bWait = sal_False).
280         if ( bWait )
281         {
282             if( pGrf->IsSwapOut() ||
283                 ( pGrfNode->IsLinkedFile() && GRAPHIC_DEFAULT == pGrf->GetType() ) )
284             {
285 #ifdef DBG_UTIL
286                 ASSERT( pGrfNode->SwapIn( bWait ) || !bWait, "Grafik konnte nicht geladen werden" );
287 #else
288                 pGrfNode->SwapIn( bWait );
289 #endif
290             }
291         }
292         else
293         {
294             if ( pGrf->IsSwapOut() && !pGrfNode->IsLinkedFile() )
295             {
296 #ifdef DBG_UTIL
297                 ASSERT( pGrfNode->SwapIn( bWait ) || !bWait, "Grafik konnte nicht geladen werden" );
298 #else
299                 pGrfNode->SwapIn( bWait );
300 #endif
301             }
302         }
303         // <--
304     }
305     return pGrf;
306     // <--
307 }
308 
309 sal_Bool SwEditShell::IsGrfSwapOut( sal_Bool bOnlyLinked ) const
310 {
311 	SwGrfNode *pGrfNode = _GetGrfNode();
312 	return pGrfNode &&
313 		(bOnlyLinked ? ( pGrfNode->IsLinkedFile() &&
314 						( GRAPHIC_DEFAULT == pGrfNode->GetGrfObj().GetType()||
315 						  pGrfNode->GetGrfObj().IsSwappedOut()))
316 					 : pGrfNode->GetGrfObj().IsSwappedOut());
317 }
318 
319 // --> OD 2005-02-09 #119353# - robust
320 const GraphicObject* SwEditShell::GetGraphicObj() const
321 {
322     SwGrfNode* pGrfNode = _GetGrfNode();
323     // --> OD 2005-02-09 #119353# - robust
324     return pGrfNode ? &(pGrfNode->GetGrfObj()) : 0L;
325     // <--
326 }
327 
328 sal_uInt16 SwEditShell::GetGraphicType() const
329 {
330 	SwGrfNode *pGrfNode = _GetGrfNode();
331     return static_cast<sal_uInt16>(pGrfNode ? pGrfNode->GetGrfObj().GetType() : GRAPHIC_NONE);
332 }
333 
334 /******************************************************************************
335  *		liefert die Groesse der Graphic, wenn CurCrsr->GetPoint() auf
336  * 			einen SwGrfNode zeigt (und GetMark nicht gesetzt ist
337  * 					oder auf die gleiche Graphic zeigt)
338  ******************************************************************************/
339 
340 sal_Bool SwEditShell::GetGrfSize(Size& rSz) const
341 {
342 	SwNoTxtNode* pNoTxtNd;
343     SwPaM* pCurrentCrsr = GetCrsr();
344     if( ( !pCurrentCrsr->HasMark()
345          || pCurrentCrsr->GetPoint()->nNode == pCurrentCrsr->GetMark()->nNode )
346          && 0 != ( pNoTxtNd = pCurrentCrsr->GetNode()->GetNoTxtNode() ) )
347 	{
348 		rSz = pNoTxtNd->GetTwipSize();
349 		return sal_True;
350 	}
351 	return sal_False;
352 
353 }
354 /******************************************************************************
355  * 		erneutes Einlesen, falls Graphic nicht Ok ist. Die
356  * 		aktuelle wird durch die neue ersetzt.
357  ******************************************************************************/
358 
359 void SwEditShell::ReRead( const String& rGrfName, const String& rFltName,
360 					const Graphic* pGraphic, const GraphicObject* pGrfObj )
361 {
362 	StartAllAction();
363 	pDoc->ReRead( *GetCrsr(), rGrfName, rFltName, pGraphic, pGrfObj );
364 	EndAllAction();
365 }
366 
367 
368 /******************************************************************************
369  *	liefert den Namen und den FilterNamen einer Graphic, wenn der Cursor
370  *	auf einer Graphic steht
371  *	Ist ein String-Ptr != 0 dann returne den entsp. Namen
372  ******************************************************************************/
373 
374 
375 void SwEditShell::GetGrfNms( String* pGrfName, String* pFltName,
376 							const SwFlyFrmFmt* pFmt ) const
377 {
378 	ASSERT( pGrfName || pFltName, "was wird denn nun erfragt?" );
379 	if( pFmt )
380 		GetDoc()->GetGrfNms( *pFmt, pGrfName, pFltName );
381 	else
382 	{
383 		SwGrfNode *pGrfNode = _GetGrfNode();
384 		if( pGrfNode && pGrfNode->IsLinkedFile() )
385 			pGrfNode->GetFileFilterNms( pGrfName, pFltName );
386 	}
387 }
388 
389 
390 // alternativen Text abfragen/setzen
391 //const String& SwEditShell::GetAlternateText() const
392 //{
393 //    SwPaM* pCrsr = GetCrsr();
394 //    const SwNoTxtNode* pNd;
395 //    if( !pCrsr->HasMark() && 0 != ( pNd = pCrsr->GetNode()->GetNoTxtNode()) )
396 //        return pNd->GetAlternateText();
397 
398 //    return aEmptyStr;
399 //}
400 
401 
402 //void SwEditShell::SetAlternateText( const String& rTxt )
403 //{
404 //    SwPaM* pCrsr = GetCrsr();
405 //    SwNoTxtNode* pNd;
406 //    if( !pCrsr->HasMark() && 0 != ( pNd = pCrsr->GetNode()->GetNoTxtNode()) )
407 //    {
408 //        pNd->SetAlternateText( rTxt, sal_True );
409 //        GetDoc()->SetModified();
410 //    }
411 //}
412 
413 
414 const PolyPolygon *SwEditShell::GetGraphicPolygon() const
415 {
416 	SwNoTxtNode *pNd = GetCrsr()->GetNode()->GetNoTxtNode();
417 	return pNd->HasContour();
418 }
419 
420 
421 void SwEditShell::SetGraphicPolygon( const PolyPolygon *pPoly )
422 {
423 	SwNoTxtNode *pNd = GetCrsr()->GetNode()->GetNoTxtNode();
424 	StartAllAction();
425 	pNd->SetContour( pPoly );
426 	SwFlyFrm *pFly = (SwFlyFrm*)pNd->getLayoutFrm(GetLayout())->GetUpper();
427 	const SwFmtSurround &rSur = pFly->GetFmt()->GetSurround();
428 	pFly->GetFmt()->NotifyClients( (SwFmtSurround*)&rSur, (SwFmtSurround*)&rSur );
429 	GetDoc()->SetModified();
430 	EndAllAction();
431 }
432 
433 void SwEditShell::ClearAutomaticContour()
434 {
435 	SwNoTxtNode *pNd = GetCrsr()->GetNode()->GetNoTxtNode();
436 	ASSERT( pNd, "is no NoTxtNode!" );
437     if( pNd->HasAutomaticContour() )
438     {
439         StartAllAction();
440         pNd->SetContour( NULL, sal_False );
441         SwFlyFrm *pFly = (SwFlyFrm*)pNd->getLayoutFrm(GetLayout())->GetUpper();
442         const SwFmtSurround &rSur = pFly->GetFmt()->GetSurround();
443         pFly->GetFmt()->NotifyClients( (SwFmtSurround*)&rSur, (SwFmtSurround*)&rSur );
444         GetDoc()->SetModified();
445         EndAllAction();
446     }
447 }
448 
449 /******************************************************************************
450  * 		liefert Pointer auf ein SvInPlaceObjectRef, wenn CurCrsr->GetPoint() auf
451  * 			einen SwOLENode zeigt (und GetMark nicht gesetzt ist
452  * 					oder auf das gleiche SvInPlaceObjectRef zeigt)
453  * 		besorgt den Pointer vom Doc wenn das Objekt per Namen gesucht werden
454  * 		soll
455  ******************************************************************************/
456 
457 svt::EmbeddedObjectRef& SwEditShell::GetOLEObject() const
458 {
459 	ASSERT(  CNT_OLE == GetCntType(), "GetOLEObj: kein OLENode." );
460 	ASSERT( !GetCrsr()->HasMark() ||
461 			(GetCrsr()->HasMark() &&
462 				GetCrsr()->GetPoint()->nNode == GetCrsr()->GetMark()->nNode),
463 			"GetOLEObj: kein OLENode." );
464 
465 	SwOLENode *pOLENode = GetCrsr()->GetNode()->GetOLENode();
466 	ASSERT( pOLENode, "GetOLEObj: kein OLENode." );
467 	SwOLEObj& rOObj = pOLENode->GetOLEObj();
468     return rOObj.GetObject();
469 }
470 
471 
472 sal_Bool SwEditShell::HasOLEObj( const String &rName ) const
473 {
474 	SwStartNode *pStNd;
475 	SwNodeIndex aIdx( *GetNodes().GetEndOfAutotext().StartOfSectionNode(), 1 );
476 	while ( 0 != (pStNd = aIdx.GetNode().GetStartNode()) )
477 	{
478 		aIdx++;
479 		SwNode& rNd = aIdx.GetNode();
480 		if( rNd.IsOLENode() &&
481 			rName == ((SwOLENode&)rNd).GetChartTblName() &&
482 			((SwOLENode&)rNd).getLayoutFrm( GetLayout() ) )
483 			return sal_True;
484 
485 		aIdx.Assign( *pStNd->EndOfSectionNode(), + 1 );
486 	}
487 	return sal_False;
488 }
489 
490 
491 void SwEditShell::SetChartName( const String &rName )
492 {
493 	SwOLENode *pONd = GetCrsr()->GetNode()->GetOLENode();
494 	ASSERT( pONd, "ChartNode not found" );
495 	pONd->SetChartTblName( rName );
496 }
497 
498 void SwEditShell::UpdateCharts( const String &rName )
499 {
500 	GetDoc()->UpdateCharts( rName );
501 }
502 
503 
504 /******************************************************************************
505  * 		Aenderung des Tabellennamens
506  ******************************************************************************/
507 
508 void SwEditShell::SetTableName( SwFrmFmt& rTblFmt, const String &rNewName )
509 {
510 	GetDoc()->SetTableName( rTblFmt, rNewName );
511 }
512 
513 // erfragen des akt. Wortes
514 
515 String SwEditShell::GetCurWord()
516 {
517     const SwPaM& rPaM = *GetCrsr();
518     const SwTxtNode* pNd = rPaM.GetNode()->GetTxtNode();
519     String aString = pNd ?
520                      pNd->GetCurWord(rPaM.GetPoint()->nContent.GetIndex()) :
521                      aEmptyStr;
522 	return aString;
523 }
524 
525 /****************************************************************************
526  *			 void SwEditShell::UpdateDocStat( SwDocStat& rStat )
527  ****************************************************************************/
528 
529 
530 void SwEditShell::UpdateDocStat( SwDocStat& rStat )
531 {
532 	StartAllAction();
533 	GetDoc()->UpdateDocStat( rStat );
534 	EndAllAction();
535 }
536 
537 // OPT: eddocinl.cxx
538 
539 
540 	// returne zum Namen die im Doc gesetzte Referenz
541 const SwFmtRefMark* SwEditShell::GetRefMark( const String& rName ) const
542 {
543 	return GetDoc()->GetRefMark( rName );
544 }
545 
546 	// returne die Namen aller im Doc gesetzten Referenzen
547 sal_uInt16 SwEditShell::GetRefMarks( SvStringsDtor* pStrings ) const
548 {
549 	return GetDoc()->GetRefMarks( pStrings );
550 }
551 
552 /******************************************************************************
553  *			DropCap-SS
554  ******************************************************************************/
555 
556 
557 String SwEditShell::GetDropTxt( const sal_uInt16 nChars ) const
558 {
559     /**
560      * pb: made changes for #i74939#
561      *
562      * always return a string even though there is a selection
563      */
564 
565 	String aTxt;
566     SwPaM* pCrsr = GetCrsr();
567     if ( IsMultiSelection() )
568     {
569         // if a multi selection exists, search for the first line
570         // -> it is the cursor with the lowest index
571         sal_uLong nIndex = pCrsr->GetMark()->nNode.GetIndex();
572         bool bPrev = true;
573         SwPaM* pLast = pCrsr;
574         SwPaM* pTemp = pCrsr;
575         while ( bPrev )
576         {
577             SwPaM* pPrev2 = dynamic_cast< SwPaM* >( pTemp->GetPrev() );
578             bPrev = ( pPrev2 && pPrev2 != pLast );
579             if ( bPrev )
580             {
581                 pTemp = pPrev2;
582                 sal_uLong nTemp = pPrev2->GetMark()->nNode.GetIndex();
583                 if ( nTemp < nIndex )
584                 {
585                     nIndex = nTemp;
586                     pCrsr = pPrev2;
587                 }
588             }
589         }
590     }
591 
592     SwTxtNode* pTxtNd = pCrsr->GetNode( !pCrsr->HasMark() )->GetTxtNode();
593     if( pTxtNd )
594     {
595         xub_StrLen nDropLen = pTxtNd->GetDropLen( nChars );
596         if( nDropLen )
597             aTxt = pTxtNd->GetTxt().Copy( 0, nDropLen );
598     }
599 
600     return aTxt;
601 }
602 
603 void SwEditShell::ReplaceDropTxt( const String &rStr )
604 {
605 	SwPaM* pCrsr = GetCrsr();
606 	if( pCrsr->GetPoint()->nNode == pCrsr->GetMark()->nNode &&
607 		pCrsr->GetNode()->GetTxtNode()->IsTxtNode() )
608 	{
609 		StartAllAction();
610 
611 		const SwNodeIndex& rNd = pCrsr->GetPoint()->nNode;
612 		SwPaM aPam( rNd, rStr.Len(), rNd, 0 );
613 		if( !GetDoc()->Overwrite( aPam, rStr ) )
614 		{
615 			ASSERT( sal_False, "Doc->Overwrite(Str) failed." );
616 		}
617 
618 		EndAllAction();
619 	}
620 }
621 
622 /******************************************************************************
623  *	Methode		:
624  *	Beschreibung:
625  *	Erstellt	:	OK 25.04.94 13:45
626  *	Aenderung	:
627  ******************************************************************************/
628 
629 String SwEditShell::Calculate()
630 {
631 	String 	aFormel;					// die entgueltige Formel
632 	SwPaM	*pPaMLast = (SwPaM*)GetCrsr()->GetNext(),
633 			*pPaM = pPaMLast;			// die Pointer auf Cursor
634 	SwCalc 	aCalc( *GetDoc() );
635 	const CharClass& rCC = GetAppCharClass();
636 
637 	do {
638 		SwTxtNode* pTxtNd = pPaM->GetNode()->GetTxtNode();
639 		if(pTxtNd)
640 		{
641 			const SwPosition *pStart = pPaM->Start(), *pEnd = pPaM->End();
642 			xub_StrLen nStt = pStart->nContent.GetIndex();
643 			String aStr = pTxtNd->GetExpandTxt( nStt, pEnd->nContent.
644 												GetIndex() - nStt );
645 
646 			rCC.toLower( aStr );
647 
648 			sal_Unicode ch;
649 			sal_Bool 	bValidFlds = sal_False;
650 			xub_StrLen nPos = 0;
651 
652 			while( nPos < aStr.Len() )
653 			{
654 				ch = aStr.GetChar( nPos++ );
655 				if( rCC.isLetter( aStr, nPos-1 ) || ch == '_' )
656 				{
657                     xub_StrLen nTmpStt = nPos-1;
658 					while(  nPos < aStr.Len() &&
659 							0 != ( ch = aStr.GetChar( nPos++ )) &&
660 						   (rCC.isLetterNumeric( aStr, nPos - 1 ) ||
661 						   	ch == '_'|| ch == '.' ))
662 						;
663 
664 					if( nPos < aStr.Len() )
665 						--nPos;
666 
667                     String sVar( aStr.Copy( nTmpStt, nPos - nTmpStt ));
668 					if( !::FindOperator( sVar ) &&
669 						(::Find( sVar, aCalc.GetVarTable(),TBLSZ) ||
670 						 aCalc.VarLook( sVar )) )
671 					{
672 						if( !bValidFlds )
673 						{
674 							GetDoc()->FldsToCalc( aCalc,
675 												  pStart->nNode.GetIndex(),
676 												  pStart->nContent.GetIndex() );
677 							bValidFlds = sal_True;
678 						}
679 						(( aFormel += '(' ) +=
680 								aCalc.GetStrResult( aCalc.VarLook( sVar )
681 														->nValue )) += ')';
682 					}
683 					else
684 						aFormel += sVar;
685 				}
686 				else
687 					aFormel += ch;
688 			}
689 		}
690 	} while( pPaMLast != (pPaM = (SwPaM*)pPaM->GetNext()) );
691 
692 	return aCalc.GetStrResult( aCalc.Calculate(aFormel) );
693 }
694 
695 
696 sfx2::LinkManager& SwEditShell::GetLinkManager()
697 {
698 	return pDoc->GetLinkManager();
699 }
700 
701 
702 void *SwEditShell::GetIMapInventor() const
703 {
704 	//Als eindeutige Identifikation sollte der Node, auf dem der Crsr steht
705 	//genuegen.
706 	return (void*)GetCrsr()->GetNode();
707 }
708 
709 // --> OD 2007-03-01 #i73788#
710 // remove default parameter, because method is always called this default value
711 Graphic SwEditShell::GetIMapGraphic() const
712 {
713 	//Liefert immer eine Graphic, wenn der Crsr in einem Fly steht.
714 	SET_CURR_SHELL( (ViewShell*)this );
715 	Graphic aRet;
716 	SwPaM* pCrsr = GetCrsr();
717 	if ( !pCrsr->HasMark() )
718 	{
719 		SwNode *pNd =pCrsr->GetNode();
720 		if( pNd->IsGrfNode() )
721 		{
722 			const Graphic& rGrf = ((SwGrfNode*)pNd)->GetGrf();
723 			if( rGrf.IsSwapOut() || ( ((SwGrfNode*)pNd)->IsLinkedFile() &&
724 									GRAPHIC_DEFAULT == rGrf.GetType() ) )
725 			{
726 #ifdef DBG_UTIL
727                 ASSERT( ((SwGrfNode*)pNd)->SwapIn( sal_True ) || !sal_True, "Grafik konnte nicht geladen werden" );
728 #else
729                 ((SwGrfNode*)pNd)->SwapIn( sal_True );
730 #endif
731 			}
732 			aRet = rGrf;
733 		}
734 		else if ( pNd->IsOLENode() )
735 		{
736             aRet = *((SwOLENode*)pNd)->GetGraphic();
737 		}
738 		else
739 		{
740 			SwFlyFrm* pFlyFrm = pNd->GetCntntNode()->getLayoutFrm( GetLayout() )->FindFlyFrm();
741 			if(pFlyFrm)
742 			    aRet = pFlyFrm->GetFmt()->MakeGraphic();
743 		}
744 	}
745 	return aRet;
746 }
747 
748 
749 sal_Bool SwEditShell::InsertURL( const SwFmtINetFmt& rFmt, const String& rStr, sal_Bool bKeepSelection )
750 {
751 	// URL und Hinweistext (direkt oder via Selektion) notwendig
752 	if( !rFmt.GetValue().Len() ||	( !rStr.Len() && !HasSelection() ) )
753 		return sal_False;
754 	StartAllAction();
755     GetDoc()->GetIDocumentUndoRedo().StartUndo( UNDO_UI_INSERT_URLTXT, NULL);
756 	sal_Bool bInsTxt = sal_True;
757 
758 	if( rStr.Len() )
759 	{
760 		SwPaM* pCrsr = GetCrsr();
761 		if( pCrsr->HasMark() && *pCrsr->GetPoint() != *pCrsr->GetMark() )
762 		{
763 			// Selection vorhanden, MehrfachSelektion?
764 			sal_Bool bDelTxt = sal_True;
765 			if( pCrsr->GetNext() == pCrsr )
766 			{
767 				// einfach Selection -> Text ueberpruefen
768 				String sTxt( GetSelTxt() );
769 				sTxt.EraseTrailingChars();
770 				if( sTxt == rStr )
771 					bDelTxt = bInsTxt = sal_False;
772 			}
773 			else if( rFmt.GetValue() == rStr )		// Name und URL gleich?
774 				bDelTxt = bInsTxt = sal_False;
775 
776 			if( bDelTxt )
777 				Delete();
778 		}
779 		else if( pCrsr->GetNext() != pCrsr && rFmt.GetValue() == rStr )
780 			bInsTxt = sal_False;
781 
782 		if( bInsTxt )
783 		{
784             Insert2( rStr );
785 			SetMark();
786 			ExtendSelection( sal_False, rStr.Len() );
787 		}
788 	}
789 	else
790 		bInsTxt = sal_False;
791 
792 	SetAttr( rFmt );
793 	if (bInsTxt && !IsCrsrPtAtEnd())
794 		SwapPam();
795 	if(!bKeepSelection)
796 		ClearMark();
797 	if( bInsTxt )
798 		DontExpandFmt();
799     GetDoc()->GetIDocumentUndoRedo().EndUndo( UNDO_UI_INSERT_URLTXT, NULL );
800 	EndAllAction();
801 	return sal_True;
802 }
803 
804 
805 sal_uInt16 SwEditShell::GetINetAttrs( SwGetINetAttrs& rArr )
806 {
807 	if( rArr.Count() )
808 		rArr.DeleteAndDestroy( 0, rArr.Count() );
809 
810 	const SwTxtNode* pTxtNd;
811 	const SwCharFmts* pFmts = GetDoc()->GetCharFmts();
812 	for( sal_uInt16 n = pFmts->Count(); 1 < n; )
813 	{
814 		SwIterator<SwTxtINetFmt,SwCharFmt> aIter(*(*pFmts)[--n]);
815 		for( SwTxtINetFmt* pFnd = aIter.First(); pFnd; pFnd = aIter.Next() )
816         {
817 			if( 0 != ( pTxtNd = pFnd->GetpTxtNode()) &&
818 				pTxtNd->GetNodes().IsDocNodes() )
819 			{
820 				SwTxtINetFmt& rAttr = *pFnd;
821 				String sTxt( pTxtNd->GetExpandTxt( *rAttr.GetStart(),
822 									*rAttr.GetEnd() - *rAttr.GetStart() ) );
823 
824 				sTxt.EraseAllChars( 0x0a );
825 				sTxt.EraseLeadingChars().EraseTrailingChars();
826 
827 				if( sTxt.Len() )
828 				{
829 					SwGetINetAttr* pNew = new SwGetINetAttr( sTxt, rAttr );
830 					rArr.C40_INSERT( SwGetINetAttr, pNew, rArr.Count() );
831 				}
832 			}
833 	}
834 	}
835 	return rArr.Count();
836 }
837 
838 
839 	// ist der Cursor in eine INetAttribut, dann wird das komplett
840 	// geloescht; inclusive des Hinweistextes (wird beim Drag&Drop gebraucht)
841 sal_Bool SwEditShell::DelINetAttrWithText()
842 {
843 	sal_Bool bRet = SelectTxtAttr( RES_TXTATR_INETFMT, sal_False );
844 	if( bRet )
845 		DeleteSel( *GetCrsr() );
846 	return bRet;
847 }
848 
849 
850 // setzen an den Textzeichenattributen das DontExpand-Flag
851 sal_Bool SwEditShell::DontExpandFmt()
852 {
853 	sal_Bool bRet = sal_False;
854 	if( !IsTableMode() && GetDoc()->DontExpandFmt( *GetCrsr()->GetPoint() ))
855 	{
856 		bRet = sal_True;
857 		CallChgLnk();
858 	}
859 	return bRet;
860 }
861 
862 SvNumberFormatter* SwEditShell::GetNumberFormatter()
863 {
864 	return GetDoc()->GetNumberFormatter();
865 }
866 
867 sal_Bool SwEditShell::RemoveInvisibleContent()
868 {
869 	StartAllAction();
870 	sal_Bool bRet = GetDoc()->RemoveInvisibleContent();
871 	EndAllAction();
872 	return bRet;
873 }
874 sal_Bool SwEditShell::ConvertFieldsToText()
875 {
876     StartAllAction();
877     sal_Bool bRet = GetDoc()->ConvertFieldsToText();
878     EndAllAction();
879     return bRet;
880 }
881 void SwEditShell::SetNumberingRestart()
882 {
883     StartAllAction();
884     Push();
885     //iterate over all text contents - body, frames, header, footer, footnote text
886     SwPaM* pCrsr = GetCrsr();
887     for(sal_uInt16 i = 0; i < 2; i++)
888     {
889         if(!i)
890             MakeFindRange(DOCPOS_START, DOCPOS_END, pCrsr); //body content
891         else
892             MakeFindRange(DOCPOS_OTHERSTART, DOCPOS_OTHEREND, pCrsr); //extra content
893         SwPosition* pSttPos = pCrsr->Start(), *pEndPos = pCrsr->End();
894         sal_uLong nCurrNd = pSttPos->nNode.GetIndex();
895         sal_uLong nEndNd = pEndPos->nNode.GetIndex();
896         if( nCurrNd <= nEndNd )
897         {
898             SwCntntFrm* pCntFrm;
899             sal_Bool bGoOn = sal_True;
900             //iterate over all paragraphs
901             while( bGoOn )
902             {
903                 SwNode* pNd = GetDoc()->GetNodes()[ nCurrNd ];
904                 switch( pNd->GetNodeType() )
905                 {
906                 case ND_TEXTNODE:
907                     if( 0 != ( pCntFrm = ((SwTxtNode*)pNd)->getLayoutFrm( GetLayout() )) )
908                     {
909                         //jump over hidden frames - ignore protection!
910                         if( !((SwTxtFrm*)pCntFrm)->IsHiddenNow() )
911                         {
912                             //if the node is numbered and the starting value of the numbering equals the
913                             //start value of the numbering rule then set this value as hard starting value
914 
915                             //get the node num
916                             // OD 2005-11-09
917                             SwTxtNode* pTxtNd( static_cast<SwTxtNode*>(pNd) );
918                             SwNumRule* pNumRule( pTxtNd->GetNumRule() );
919 
920                             if ( pNumRule && pTxtNd->GetNum() &&
921                                  ( pTxtNd->HasNumber() || pTxtNd->HasBullet() ) &&
922                                  pTxtNd->IsCountedInList() &&
923                                  !pTxtNd->IsListRestart() &&
924                                  pTxtNd->GetNum()->GetNumber() ==
925                                     pNumRule->Get( static_cast<sal_uInt16>(pTxtNd->GetActualListLevel()) ).GetStart() )
926                             {
927                                 //now set a the start value as attribute
928                                 SwPosition aCurrentNode(*pNd);
929                                 GetDoc()->SetNumRuleStart( aCurrentNode, sal_True );
930                             }
931                         }
932                     }
933                     break;
934                 case ND_SECTIONNODE:
935                     // jump over hidden sections  - ignore protection!
936                     if(((SwSectionNode*)pNd)->GetSection().IsHidden() )
937                         nCurrNd = pNd->EndOfSectionIndex();
938                     break;
939                 case ND_ENDNODE:
940                     {
941                         break;
942                     }
943                 }
944 
945                 bGoOn = nCurrNd < nEndNd;
946                 ++nCurrNd;
947             }
948         }
949     }
950 
951 
952     Pop(sal_False);
953     EndAllAction();
954 }
955 
956 sal_uInt16 SwEditShell::GetLineCount( sal_Bool bActPos )
957 {
958 	sal_uInt16 nRet = 0;
959 	CalcLayout();
960 	SwPaM* pPam = GetCrsr();
961 	SwNodeIndex& rPtIdx = pPam->GetPoint()->nNode;
962 	SwNodeIndex aStart( rPtIdx );
963 	SwCntntNode* pCNd;
964 	SwCntntFrm *pCntFrm = 0;
965 	sal_uLong nTmpPos;
966 
967 	if( !bActPos )
968 		aStart = 0;
969 	else if( rPtIdx > ( nTmpPos = GetDoc()->GetNodes().GetEndOfExtras().GetIndex()) )
970 		// BodyBereich => Start ist EndOfIcons + 1
971 		aStart = nTmpPos + 1;
972 	else
973 	{
974 		if( 0 != ( pCNd = pPam->GetCntntNode() ) &&
975 			0 != ( pCntFrm = pCNd->getLayoutFrm( GetLayout() ) ) )
976 		{
977 			const SwStartNode *pTmp;
978 			if( pCntFrm->IsInFly() )						// Fly
979 				pTmp = pCNd->FindFlyStartNode();
980 			else if( pCntFrm->IsInFtn() )					// Footnote
981 				pTmp = pCNd->FindFootnoteStartNode();
982 			else
983 			{												// Footer/Header
984 				const sal_uInt16 nTyp = FRM_HEADER | FRM_FOOTER;
985 				SwFrm* pFrm = pCntFrm;
986 				while( pFrm && !(pFrm->GetType() & nTyp) )
987 					pFrm = pFrm->GetUpper();
988 				ASSERT( pFrm, "Wo bin ich?" );
989 				if( pFrm && ( pFrm->GetType() & FRM_FOOTER ) )
990 					pTmp = pCNd->FindFooterStartNode();
991 				else
992 					pTmp = pCNd->FindHeaderStartNode();
993 			}
994 			ASSERT( pTmp, "Missing StartNode" );
995 			aStart  = *pTmp;
996 		}
997 		ASSERT( pCNd && pCntFrm, "Missing Layout-Information" );
998 	}
999 
1000 	while( 0 != ( pCNd = GetDoc()->GetNodes().GoNextSection(
1001 				&aStart, sal_True, sal_False )) && ( !bActPos || aStart <= rPtIdx ) )
1002 	{
1003 		if( 0 != ( pCntFrm = pCNd->getLayoutFrm( GetLayout() ) ) && pCntFrm->IsTxtFrm() )
1004 		{
1005 			xub_StrLen nActPos = bActPos && aStart == rPtIdx ?
1006 				pPam->GetPoint()->nContent.GetIndex() : USHRT_MAX;
1007 			nRet = nRet + ((SwTxtFrm*)pCntFrm)->GetLineCount( nActPos );
1008 		}
1009 	}
1010 	return nRet;
1011 }
1012 
1013 long SwEditShell::CompareDoc( const SwDoc& rDoc )
1014 {
1015 	StartAllAction();
1016 	long nRet = GetDoc()->CompareDoc( rDoc );
1017 	EndAllAction();
1018 	return nRet;
1019 }
1020 
1021 long SwEditShell::MergeDoc( const SwDoc& rDoc )
1022 {
1023 	StartAllAction();
1024 	long nRet = GetDoc()->MergeDoc( rDoc );
1025 	EndAllAction();
1026 	return nRet;
1027 }
1028 
1029 
1030 const SwFtnInfo& SwEditShell::GetFtnInfo() const
1031 {
1032 	return GetDoc()->GetFtnInfo();
1033 }
1034 
1035 void SwEditShell::SetFtnInfo(const SwFtnInfo& rInfo)
1036 {
1037 	StartAllAction();
1038 	SET_CURR_SHELL( this );
1039 	GetDoc()->SetFtnInfo(rInfo);
1040 	CallChgLnk();
1041 	EndAllAction();
1042 }
1043 
1044 const SwEndNoteInfo& SwEditShell::GetEndNoteInfo() const
1045 {
1046 	return GetDoc()->GetEndNoteInfo();
1047 }
1048 
1049 void SwEditShell::SetEndNoteInfo(const SwEndNoteInfo& rInfo)
1050 {
1051 	StartAllAction();
1052 	SET_CURR_SHELL( this );
1053 	GetDoc()->SetEndNoteInfo(rInfo);
1054 	EndAllAction();
1055 }
1056 
1057 const SwLineNumberInfo& SwEditShell::GetLineNumberInfo() const
1058 {
1059 	return GetDoc()->GetLineNumberInfo();
1060 }
1061 
1062 void SwEditShell::SetLineNumberInfo(const SwLineNumberInfo& rInfo)
1063 {
1064 	StartAllAction();
1065 	SET_CURR_SHELL( this );
1066 	GetDoc()->SetLineNumberInfo(rInfo);
1067 	AddPaintRect( GetLayout()->Frm() );
1068 	EndAllAction();
1069 }
1070 
1071 sal_uInt16 SwEditShell::GetLinkUpdMode(sal_Bool bDocSettings) const
1072 {
1073     return getIDocumentSettingAccess()->getLinkUpdateMode( !bDocSettings );
1074 }
1075 
1076 void SwEditShell::SetLinkUpdMode( sal_uInt16 nMode )
1077 {
1078     getIDocumentSettingAccess()->setLinkUpdateMode( nMode );
1079 }
1080 
1081 
1082 // Schnittstelle fuer die TextInputDaten - ( fuer die Texteingabe
1083 // von japanischen/chinesischen Zeichen)
1084 SwExtTextInput* SwEditShell::CreateExtTextInput(LanguageType eInputLanguage)
1085 {
1086 	SwExtTextInput* pRet = GetDoc()->CreateExtTextInput( *GetCrsr() );
1087     pRet->SetLanguage(eInputLanguage);
1088 	pRet->SetOverwriteCursor( SwCrsrShell::IsOverwriteCrsr() );
1089 	return pRet;
1090 }
1091 
1092 String SwEditShell::DeleteExtTextInput( SwExtTextInput* pDel, sal_Bool bInsText )
1093 {
1094 	if( !pDel )
1095 	{
1096 		const SwPosition& rPos = *GetCrsr()->GetPoint();
1097 		pDel = GetDoc()->GetExtTextInput( rPos.nNode.GetNode(),
1098 										  rPos.nContent.GetIndex() );
1099 		if( !pDel )
1100 		{
1101 			//JP 25.10.2001: under UNIX the cursor is moved before the Input-
1102 			//				Engine event comes in. So take any - normally there
1103 			//				exist only one at the time. -- Task 92016
1104 			pDel = GetDoc()->GetExtTextInput();
1105 		}
1106 	}
1107     String sRet;
1108 	if( pDel )
1109 	{
1110         rtl::OUString sTmp;
1111         SwUnoCursorHelper::GetTextFromPam(*pDel, sTmp);
1112         sRet = sTmp;
1113         SET_CURR_SHELL( this );
1114 		StartAllAction();
1115 		pDel->SetInsText( bInsText );
1116 		SetOverwriteCrsr( pDel->IsOverwriteCursor() );
1117     	const SwPosition aPos( *pDel->GetPoint() );
1118         GetDoc()->DeleteExtTextInput( pDel );
1119 
1120         // In this case, the "replace" function did not set the cursor
1121         // to the original position. Therefore we have to do this manually.
1122         if ( ! bInsText && IsOverwriteCrsr() )
1123             *GetCrsr()->GetPoint() = aPos;
1124 
1125 		EndAllAction();
1126 	}
1127     return sRet;
1128 }
1129 
1130 void SwEditShell::SetExtTextInputData( const CommandExtTextInputData& rData )
1131 {
1132 	const SwPosition& rPos = *GetCrsr()->GetPoint();
1133 	SwExtTextInput* pInput = GetDoc()->GetExtTextInput( rPos.nNode.GetNode()
1134 												/*, rPos.nContent.GetIndex()*/ );
1135 	if( pInput )
1136 	{
1137 		StartAllAction();
1138 		SET_CURR_SHELL( this );
1139 
1140 		if( !rData.IsOnlyCursorChanged() )
1141 			pInput->SetInputData( rData );
1142 		// Cursor positionieren:
1143 		const SwPosition& rStt = *pInput->Start();
1144 		xub_StrLen nNewCrsrPos = rStt.nContent.GetIndex() + rData.GetCursorPos();
1145 
1146 		// zwar unschoen aber was hilfts
1147 		ShowCrsr();
1148 		long nDiff = nNewCrsrPos - rPos.nContent.GetIndex();
1149 		if( 0 > nDiff )
1150             Left( (xub_StrLen)-nDiff, CRSR_SKIP_CHARS );
1151 		else if( 0 < nDiff )
1152             Right( (xub_StrLen)nDiff, CRSR_SKIP_CHARS );
1153 
1154 		SetOverwriteCrsr( rData.IsCursorOverwrite() );
1155 
1156 		EndAllAction();
1157 
1158 		if( !rData.IsCursorVisible() )	// must be called after the EndAction
1159 			HideCrsr();
1160 	}
1161 }
1162 
1163 void SwEditShell::TransliterateText( sal_uInt32 nType )
1164 {
1165     utl::TransliterationWrapper aTrans( ::comphelper::getProcessServiceFactory(), nType );
1166 	StartAllAction();
1167 	SET_CURR_SHELL( this );
1168 
1169 	SwPaM* pCrsr = GetCrsr();
1170 	if( pCrsr->GetNext() != pCrsr )
1171 	{
1172         GetDoc()->GetIDocumentUndoRedo().StartUndo(UNDO_EMPTY, NULL);
1173 		FOREACHPAM_START( this )
1174 
1175 		if( PCURCRSR->HasMark() )
1176 			GetDoc()->TransliterateText( *PCURCRSR, aTrans );
1177 
1178 		FOREACHPAM_END()
1179         GetDoc()->GetIDocumentUndoRedo().EndUndo(UNDO_EMPTY, NULL);
1180 	}
1181 	else
1182 		GetDoc()->TransliterateText( *pCrsr, aTrans );
1183 
1184 	EndAllAction();
1185 }
1186 
1187 void SwEditShell::CountWords( SwDocStat& rStat ) const
1188 {
1189     FOREACHPAM_START( this )
1190 
1191         if( PCURCRSR->HasMark() )
1192             GetDoc()->CountWords( *PCURCRSR, rStat );
1193 
1194     FOREACHPAM_END()
1195 }
1196 
1197 void SwEditShell::ApplyViewOptions( const SwViewOption &rOpt )
1198 {
1199 	SwCrsrShell::StartAction();
1200 	ViewShell::ApplyViewOptions( rOpt );
1201 	SwEditShell::EndAction();
1202 }
1203 
1204 
1205