xref: /AOO41X/main/sw/source/ui/wrtsh/select.cxx (revision 5ff14ef2c455a7c2a39819566d74aed4bcc9528e)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sw.hxx"
26 
27 
28 #include <limits.h>
29 #include <hintids.hxx>
30 #include <sfx2/bindings.hxx>
31 #include <svl/eitem.hxx>
32 #include <svl/macitem.hxx>
33 #include <unotools/charclass.hxx>
34 #include <editeng/scripttypeitem.hxx>
35 #include <cmdid.h>
36 #include <view.hxx>
37 #include <basesh.hxx>
38 #include <wrtsh.hxx>
39 #include <frmatr.hxx>
40 #include <initui.hxx>
41 #include <mdiexp.hxx>
42 #include <fmtcol.hxx>
43 #include <frmfmt.hxx>
44 #include <swundo.hxx>               	// fuer Undo-Ids
45 #include <swevent.hxx>
46 #include <swdtflvr.hxx>
47 #include <crsskip.hxx>
48 
49 //IAccessibility2 Implementation 2009-----
50 #ifndef _DOC_HXX
51 #include <doc.hxx>
52 #endif
53 //-----IAccessibility2 Implementation 2009
54 #if OSL_DEBUG_LEVEL > 1
55 #include <pam.hxx>
56 #endif
57 
58 namespace com { namespace sun { namespace star { namespace util {
59 	struct SearchOptions;
60 } } } }
61 
62 using namespace ::com::sun::star::util;
63 
64 
65 static long nStartDragX = 0, nStartDragY = 0;
66 static sal_Bool  bStartDrag = sal_False;
67 
68 void SwWrtShell::Invalidate()
69 {
70 	// to avoid making the slot volatile, invalidate it everytime if something could have been changed
71 	// this is still much cheaper than asking for the state every 200 ms (and avoid background processing)
72 	GetView().GetViewFrame()->GetBindings().Invalidate( FN_STAT_SELMODE );
73 }
74 
75 sal_Bool SwWrtShell::SelNearestWrd()
76 {
77 	MV_KONTEXT(this);
78 	if( !IsInWrd() && !IsEndWrd() && !IsSttWrd() )
79 		PrvWrd();
80 	if( IsEndWrd() )
81 		Left(CRSR_SKIP_CELLS, sal_False, 1, sal_False );
82 	return SelWrd();
83 }
84 
85 
86 
87 sal_Bool SwWrtShell::SelWrd(const Point *pPt, sal_Bool )
88 {
89 	sal_Bool bRet;
90 	{
91 		MV_KONTEXT(this);
92 		SttSelect();
93 		bRet = SwCrsrShell::SelectWord( pPt );
94 	}
95 	EndSelect();
96 	if( bRet )
97 	{
98 		bSelWrd = sal_True;
99 		if(pPt)
100 			aStart = *pPt;
101 	}
102 	return bRet;
103 }
104 
105 void SwWrtShell::SelSentence(const Point *pPt, sal_Bool )
106 {
107 	{
108 		MV_KONTEXT(this);
109 		ClearMark();
110         SwCrsrShell::GoStartSentence();
111 		SttSelect();
112         SwCrsrShell::GoEndSentence();
113 	}
114 	EndSelect();
115 	if(pPt)
116 		aStart = *pPt;
117 	bSelLn = sal_True;
118 	bSelWrd = sal_False;	// SelWord abschalten, sonst geht kein SelLine weiter
119 }
120 
121 void SwWrtShell::SelPara(const Point *pPt, sal_Bool )
122 {
123     {
124         MV_KONTEXT(this);
125         ClearMark();
126         SwCrsrShell::MovePara( fnParaCurr, fnParaStart );
127         SttSelect();
128         SwCrsrShell::MovePara( fnParaCurr, fnParaEnd );
129     }
130     EndSelect();
131     if(pPt)
132         aStart = *pPt;
133     bSelLn = sal_False;
134     bSelWrd = sal_False;    // SelWord abschalten, sonst geht kein SelLine weiter
135 }
136 
137 
138 long SwWrtShell::SelAll()
139 {
140     const sal_Bool bLockedView = IsViewLocked();
141     LockView( sal_True );
142     {
143         if(bBlockMode)
144             LeaveBlockMode();
145         MV_KONTEXT(this);
146         sal_Bool bMoveTable = sal_False;
147         SwPosition *pStartPos = 0;
148         SwPosition *pEndPos = 0;
149         SwShellCrsr* pTmpCrsr = 0;
150         if( !HasWholeTabSelection() )
151         {
152             if ( IsSelection() && IsCrsrPtAtEnd() )
153                 SwapPam();
154             pTmpCrsr = getShellCrsr( false );
155             if( pTmpCrsr )
156             {
157                 pStartPos = new SwPosition( *pTmpCrsr->GetPoint() );
158                 pEndPos = new SwPosition( *pTmpCrsr->GetMark() );
159             }
160             Push();
161             sal_Bool bIsFullSel = !MoveSection( fnSectionCurr, fnSectionStart);
162             SwapPam();
163             bIsFullSel &= !MoveSection( fnSectionCurr, fnSectionEnd);
164             Pop(sal_False);
165             GoStart(sal_True, &bMoveTable, sal_False, !bIsFullSel);
166         }
167         else
168         {
169             EnterStdMode();
170             SttEndDoc(sal_True);
171         }
172         SttSelect();
173         GoEnd(sal_True, &bMoveTable);
174 
175 		//IAccessibility2 Implementation 2009-----
176 		SwDoc *pDoc = GetDoc();
177 		if ( pDoc )
178 		{
179 			pDoc->SetPrepareSelAll();
180 		}
181 		//-----IAccessibility2 Implementation 2009
182         if( pStartPos )
183         {
184             pTmpCrsr = getShellCrsr( false );
185             if( pTmpCrsr )
186             {
187                 // Some special handling for sections (e.g. TOC) at the beginning of the document body
188                 // to avoid the selection of the first section
189                 // if the last selection was behind the first section or
190                 // if the last selection was already the first section
191                 // In this both cases we select to the end of document
192                 if( *pTmpCrsr->GetPoint() < *pEndPos ||
193                     ( *pStartPos == *pTmpCrsr->GetMark() &&
194                       *pEndPos == *pTmpCrsr->GetPoint() ) )
195                     SwCrsrShell::SttEndDoc(sal_False);
196             }
197             delete pStartPos;
198             delete pEndPos;
199         }
200     }
201     EndSelect();
202     LockView( bLockedView );
203     return 1;
204 }
205 
206 /*------------------------------------------------------------------------
207  Beschreibung:	Textsuche
208 ------------------------------------------------------------------------*/
209 
210 
211 sal_uLong SwWrtShell::SearchPattern( const SearchOptions& rSearchOpt, sal_Bool bSearchInNotes,
212 								SwDocPositions eStt, SwDocPositions eEnd,
213 								FindRanges eFlags, int bReplace )
214 {
215 		// keine Erweiterung bestehender Selektionen
216 	if(!(eFlags & FND_IN_SEL))
217 		ClearMark();
218     sal_Bool bCancel = sal_False;
219     sal_uLong nRet = Find( rSearchOpt, bSearchInNotes, eStt, eEnd, bCancel, eFlags, bReplace );
220     if(bCancel)
221     {
222         Undo(1);
223         nRet = ULONG_MAX;
224     }
225     return nRet;
226 }
227 /*------------------------------------------------------------------------
228  Beschreibung:	Suche nach Vorlagen
229 ------------------------------------------------------------------------*/
230 
231 
232 
233 sal_uLong SwWrtShell::SearchTempl( const String &rTempl,
234 							   SwDocPositions eStt, SwDocPositions eEnd,
235 							   FindRanges eFlags, const String* pReplTempl )
236 {
237 		// keine Erweiterung bestehender Selektionen
238 	if(!(eFlags & FND_IN_SEL))
239 		ClearMark();
240 	SwTxtFmtColl *pColl = GetParaStyle(rTempl, SwWrtShell::GETSTYLE_CREATESOME);
241 	SwTxtFmtColl *pReplaceColl = 0;
242 	if( pReplTempl )
243 		pReplaceColl = GetParaStyle(*pReplTempl, SwWrtShell::GETSTYLE_CREATESOME );
244 
245     sal_Bool bCancel = sal_False;
246     sal_uLong nRet = Find(pColl? *pColl: GetDfltTxtFmtColl(),
247 							   eStt,eEnd, bCancel, eFlags, pReplaceColl);
248     if(bCancel)
249     {
250         Undo(1);
251         nRet = ULONG_MAX;
252     }
253 	return nRet;
254 }
255 
256 // Suche nach Attributen ----------------------------------------------------
257 
258 
259 
260 sal_uLong SwWrtShell::SearchAttr( const SfxItemSet& rFindSet, sal_Bool bNoColls,
261 								SwDocPositions eStart, SwDocPositions eEnde,
262 								FindRanges eFlags, const SearchOptions* pSearchOpt,
263 								const SfxItemSet* pReplaceSet )
264 {
265 	// Keine Erweiterung bestehender Selektionen
266 	if (!(eFlags & FND_IN_SEL))
267 		ClearMark();
268 
269 	// Suchen
270     sal_Bool bCancel = sal_False;
271 	sal_uLong nRet = Find( rFindSet, bNoColls, eStart, eEnde, bCancel, eFlags, pSearchOpt, pReplaceSet);
272 
273     if(bCancel)
274     {
275         Undo(1);
276         nRet = ULONG_MAX;
277     }
278 	return nRet;
279 }
280 
281 // ---------- Selektionsmodi ----------
282 
283 
284 
285 void SwWrtShell::PushMode()
286 {
287 	pModeStack = new ModeStack( pModeStack, bIns, bExtMode, bAddMode, bBlockMode );
288 }
289 
290 
291 
292 void SwWrtShell::PopMode()
293 {
294 	if ( 0 == pModeStack )
295 		return;
296 
297 	if ( bExtMode && !pModeStack->bExt )
298 		LeaveExtMode();
299 	if ( bAddMode && !pModeStack->bAdd )
300 		LeaveAddMode();
301 	if ( bBlockMode && !pModeStack->bBlock )
302 		LeaveBlockMode();
303 	bIns = pModeStack->bIns;
304 
305 	ModeStack *pTmp = pModeStack->pNext;
306 	delete pModeStack;
307 	pModeStack = pTmp;
308 }
309 
310 /*
311  * Zwei Methoden fuer das Cursorsetzen; die erste mappt auf die
312  * gleichnamige Methoden an der CursorShell, die zweite hebt
313  * zuerst alle Selektionen auf.
314  */
315 
316 
317 
318 long SwWrtShell::SetCrsr(const Point *pPt, sal_Bool bTextOnly)
319 {
320 		/*
321 		* eine gfs.  bestehende Selektion an der Position des
322 		* Mausklicks aufheben
323 		*/
324 	if(!IsInSelect() && ChgCurrPam(*pPt)) {
325 		ClearMark();
326 	}
327 
328 	return SwCrsrShell::SetCrsr(*pPt, bTextOnly);
329 }
330 
331 
332 long SwWrtShell::SetCrsrKillSel(const Point *pPt, sal_Bool bTextOnly )
333 {
334 	ACT_KONTEXT(this);
335 	ResetSelect(pPt,sal_False);
336     return SwCrsrShell::SetCrsr(*pPt, bTextOnly);
337 }
338 
339 
340 
341 void SwWrtShell::UnSelectFrm()
342 {
343     // Rahmenselektion aufheben mit garantiert ungueltiger Position
344 	Point aPt(LONG_MIN, LONG_MIN);
345     SelectObj(aPt, 0);
346 	SwTransferable::ClearSelection( *this );
347 }
348 
349 /*
350  * Aufheben aller Selektionen
351  */
352 
353 
354 
355 long SwWrtShell::ResetSelect(const Point *,sal_Bool)
356 {
357 	if(IsSelFrmMode())
358 	{
359 		UnSelectFrm();
360 		LeaveSelFrmMode();
361 	}
362 	else
363 	{
364 		/* 	ACT_KONTEXT() macht eine Action auf -
365 			um im Basicablauf keine Probleme mit der
366 			Shellumschaltung zu bekommen, darf
367 			GetChgLnk().Call() erst nach
368 			EndAction() gerufen werden.
369 		*/
370 		{
371 			ACT_KONTEXT(this);
372 			bSelWrd = bSelLn = sal_False;
373 			KillPams();
374 			ClearMark();
375             fnKillSel = &SwWrtShell::Ignore;
376 			fnSetCrsr = &SwWrtShell::SetCrsr;
377 		}
378 		/*
379 			* nach dem Aufheben aller Selektionen koennte ein Update der
380 			* Attr-Controls notwendig sein.
381 		*/
382 		GetChgLnk().Call(this);
383 	}
384 	Invalidate();
385 	SwTransferable::ClearSelection( *this );
386 	return 1;
387 }
388 
389 
390 
391 /*
392  * tue nichts
393  */
394 long SwWrtShell::Ignore(const Point *, sal_Bool ) {
395 	return 1;
396 }
397 
398 /*
399  * Start eines Selektionsvorganges.
400  */
401 
402 
403 
404 void SwWrtShell::SttSelect()
405 {
406 	if(bInSelect)
407 		return;
408 	if(!HasMark())
409 		SetMark();
410     if( bBlockMode )
411     {
412         SwShellCrsr* pTmp = getShellCrsr( true );
413         if( !pTmp->HasMark() )
414             pTmp->SetMark();
415     }
416 	fnKillSel = &SwWrtShell::Ignore;
417 	fnSetCrsr = &SwWrtShell::SetCrsr;
418 	bInSelect = sal_True;
419 	Invalidate();
420 	SwTransferable::CreateSelection( *this );
421 }
422 /*
423  * Ende eines Selektionsvorganges.
424  */
425 
426 
427 
428 void SwWrtShell::EndSelect()
429 {
430 	if(!bInSelect || bExtMode)
431 		return;
432 	bInSelect = sal_False;
433 	(this->*fnLeaveSelect)(0,sal_False);
434 	if(!bAddMode) {
435 		fnSetCrsr = &SwWrtShell::SetCrsrKillSel;
436 		fnKillSel = &SwWrtShell::ResetSelect;
437 	}
438 }
439 /* Methode, um eine bestehende wortweise oder zeilenweise Selektion
440  * zu erweitern.
441  */
442 
443 inline sal_Bool operator<(const Point &rP1,const Point &rP2)
444 {
445 	return rP1.Y() < rP2.Y() || (rP1.Y() == rP2.Y() && rP1.X() < rP2.X());
446 }
447 
448 
449 
450 long SwWrtShell::ExtSelWrd(const Point *pPt, sal_Bool )
451 {
452 	MV_KONTEXT(this);
453 	if( IsTableMode() )
454 		return 1;
455 
456 	// Bug 66823: actual crsr has in additional mode no selection?
457 	// Then destroy the actual an go to prev, this will be expand
458 	if( !HasMark() && GoPrevCrsr() )
459 	{
460 		sal_Bool bHasMark = HasMark(); // thats wrong!
461 		GoNextCrsr();
462 		if( bHasMark )
463 		{
464 			DestroyCrsr();
465 			GoPrevCrsr();
466 		}
467 	}
468 
469 	// check the direction of the selection with the new point
470 	sal_Bool bRet = sal_False, bMoveCrsr = sal_True, bToTop = sal_False;
471 	SwCrsrShell::SelectWord( &aStart );  	// select the startword
472 	SwCrsrShell::Push();					// save the cursor
473 	SwCrsrShell::SetCrsr( *pPt );			// and check the direction
474 
475 	switch( SwCrsrShell::CompareCursor( StackMkCurrPt ))
476 	{
477 	case -1:	bToTop = sal_False; 	break;
478 	case 1: 	bToTop = sal_True;		break;
479 	default:	bMoveCrsr = sal_False;	break;
480 	}
481 
482 	SwCrsrShell::Pop( sal_False );				// retore the saved cursor
483 
484 	if( bMoveCrsr )
485 	{
486 		// select to Top but cursor select to Bottom? or
487 		// select to Bottom but cursor select to Top? 		--> swap the cursor
488 		if( bToTop )
489 			SwapPam();
490 
491 		SwCrsrShell::Push();		        // save cur cursor
492 		if( SwCrsrShell::SelectWord( pPt ))	// select the current word
493 		{
494 			if( bToTop )
495 				SwapPam();
496 			Combine();
497 			bRet = sal_True;
498 		}
499 		else
500 		{
501 			SwCrsrShell::Pop( sal_False );
502 			if( bToTop )
503 				SwapPam();
504 		}
505 	}
506 	else
507 		bRet = sal_True;
508 	return bRet;
509 }
510 
511 
512 long SwWrtShell::ExtSelLn(const Point *pPt, sal_Bool )
513 {
514 	MV_KONTEXT(this);
515 	SwCrsrShell::SetCrsr(*pPt);
516 	if( IsTableMode() )
517 		return 1;
518 
519 	// Bug 66823: actual crsr has in additional mode no selection?
520 	// Then destroy the actual an go to prev, this will be expand
521 	if( !HasMark() && GoPrevCrsr() )
522 	{
523 		sal_Bool bHasMark = HasMark(); // thats wrong!
524 		GoNextCrsr();
525 		if( bHasMark )
526 		{
527 			DestroyCrsr();
528 			GoPrevCrsr();
529 		}
530 	}
531 
532 	// ggfs. den Mark der Selektion anpassen
533 	sal_Bool bToTop = !IsCrsrPtAtEnd();
534 	SwapPam();
535 
536 	// der "Mark" muss am Zeilenende/-anfang stehen
537     if( bToTop ? !IsEndSentence() : !IsStartSentence() )
538 	{
539 		if( bToTop )
540 		{
541 			if( !IsEndPara() )
542 				SwCrsrShell::Right(1,CRSR_SKIP_CHARS);
543             SwCrsrShell::GoEndSentence();
544 		}
545 		else
546             SwCrsrShell::GoStartSentence();
547 	}
548 	SwapPam();
549 
550     return bToTop ? SwCrsrShell::GoStartSentence() : SwCrsrShell::GoEndSentence();
551 }
552 
553 
554 /*
555  * zurueck in den Standard Mode: kein Mode, keine Selektionen.
556  */
557 
558 void SwWrtShell::EnterStdMode()
559 {
560 	if(bAddMode)
561 		LeaveAddMode();
562 	if(bBlockMode)
563 		LeaveBlockMode();
564 	bBlockMode = sal_False;
565 	bExtMode = sal_False;
566 	bInSelect = sal_False;
567     if(IsSelFrmMode())
568     {
569         UnSelectFrm();
570         LeaveSelFrmMode();
571     }
572     else
573     {
574         /*  ACT_KONTEXT() opens and action which has to be
575             closed prior to the call of
576             GetChgLnk().Call()
577         */
578         {
579             ACT_KONTEXT(this);
580             bSelWrd = bSelLn = sal_False;
581             if( !IsRetainSelection() )
582                 KillPams();
583             ClearMark();
584             fnSetCrsr = &SwWrtShell::SetCrsrKillSel;
585             fnKillSel = &SwWrtShell::ResetSelect;
586         }
587     }
588 	Invalidate();
589     SwTransferable::ClearSelection( *this );
590 }
591 
592 /*
593  * Extended Mode
594  */
595 
596 
597 
598 void SwWrtShell::EnterExtMode()
599 {
600 	if(bBlockMode)
601 	{
602 		LeaveBlockMode();
603 		KillPams();
604 		ClearMark();
605 	}
606 	bExtMode = sal_True;
607 	bAddMode = sal_False;
608 	bBlockMode = sal_False;
609 	SttSelect();
610 }
611 
612 
613 
614 void SwWrtShell::LeaveExtMode()
615 {
616 	bExtMode = sal_False;
617 	EndSelect();
618 }
619 /*
620  * Ende einer Selektion; falls die Selektion leer ist,
621  * ClearMark().
622  */
623 
624 
625 
626 long SwWrtShell::SttLeaveSelect(const Point *, sal_Bool )
627 {
628 	if(SwCrsrShell::HasSelection() && !IsSelTblCells() && bClearMark) {
629 		return 0;
630 	}
631 //	if( IsSelTblCells() ) aSelTblLink.Call(this);
632 	ClearMark();
633 	return 1;
634 }
635 /*
636  * Verlassen des Selektionsmodus in Additional Mode
637  */
638 
639 
640 
641 long SwWrtShell::AddLeaveSelect(const Point *, sal_Bool )
642 {
643 	if(IsTableMode()) LeaveAddMode();
644 	else if(SwCrsrShell::HasSelection())
645 		CreateCrsr();
646 	return 1;
647 }
648 /*
649  * Additional Mode
650  */
651 
652 
653 
654 void SwWrtShell::EnterAddMode()
655 {
656 	if(IsTableMode()) return;
657 	if(bBlockMode)
658 		LeaveBlockMode();
659 	fnLeaveSelect = &SwWrtShell::AddLeaveSelect;
660 	fnKillSel = &SwWrtShell::Ignore;
661 	fnSetCrsr = &SwWrtShell::SetCrsr;
662 	bAddMode = sal_True;
663 	bBlockMode = sal_False;
664 	bExtMode = sal_False;
665 	if(SwCrsrShell::HasSelection())
666 		CreateCrsr();
667 	Invalidate();
668 }
669 
670 
671 
672 void SwWrtShell::LeaveAddMode()
673 {
674 	fnLeaveSelect = &SwWrtShell::SttLeaveSelect;
675 	fnKillSel = &SwWrtShell::ResetSelect;
676 	fnSetCrsr = &SwWrtShell::SetCrsrKillSel;
677 	bAddMode = sal_False;
678 	Invalidate();
679 }
680 
681 /*
682  * Block Mode
683  */
684 
685 void SwWrtShell::EnterBlockMode()
686 {
687     bBlockMode = sal_False;
688     EnterStdMode();
689 	bBlockMode = sal_True;
690     CrsrToBlockCrsr();
691 	Invalidate();
692 }
693 
694 
695 
696 void SwWrtShell::LeaveBlockMode()
697 {
698 	bBlockMode = sal_False;
699     BlockCrsrToCrsr();
700 	EndSelect();
701 	Invalidate();
702 }
703 
704 // Einfuegemodus
705 
706 
707 
708 void SwWrtShell::SetInsMode( sal_Bool bOn )
709 {
710 	bIns = bOn;
711 	SwCrsrShell::SetOverwriteCrsr( !bIns );
712 	const SfxBoolItem aTmp( SID_ATTR_INSERT, bIns );
713 	GetView().GetViewFrame()->GetBindings().SetState( aTmp );
714 	StartAction();
715 	EndAction();
716 	Invalidate();
717 }
718 //Overwrite mode is incompatible with red-lining
719 void SwWrtShell::SetRedlineModeAndCheckInsMode( sal_uInt16 eMode )
720 {
721    SetRedlineMode( eMode );
722    if (IsRedlineOn())
723        SetInsMode( true );
724 }
725 
726 /*
727  * Rahmen bearbeiten
728  */
729 
730 
731 long SwWrtShell::BeginFrmDrag(const Point *pPt, sal_Bool)
732 {
733 	fnDrag = &SwFEShell::Drag;
734 	if(bStartDrag)
735 	{
736 		Point aTmp( nStartDragX, nStartDragY );
737 		SwFEShell::BeginDrag( &aTmp, sal_False );
738 	}
739 	else
740 		SwFEShell::BeginDrag( pPt, sal_False );
741 	return 1;
742 }
743 
744 
745 
746 void SwWrtShell::EnterSelFrmMode(const Point *pPos)
747 {
748 	if(pPos)
749 	{
750 		nStartDragX = pPos->X();
751 		nStartDragY = pPos->Y();
752 		bStartDrag = sal_True;
753 	}
754 	bNoEdit = bLayoutMode = sal_True;
755 	HideCrsr();
756 
757 		// gleicher Aufruf von BeginDrag an der SwFEShell
758 	fnDrag			= &SwWrtShell::BeginFrmDrag;
759 	fnEndDrag		= &SwWrtShell::UpdateLayoutFrm;
760 	SwBaseShell::SetFrmMode( FLY_DRAG_START, this );
761 	Invalidate();
762 }
763 
764 
765 
766 void SwWrtShell::LeaveSelFrmMode()
767 {
768 	fnDrag			= &SwWrtShell::BeginDrag;
769 	fnEndDrag		= &SwWrtShell::EndDrag;
770 	bLayoutMode = sal_False;
771 	bStartDrag = sal_False;
772 	Edit();
773 	SwBaseShell::SetFrmMode( FLY_DRAG_END, this );
774 	Invalidate();
775 }
776 /*------------------------------------------------------------------------
777  Beschreibung:	Rahmengebundenes Macro ausfuehren
778 ------------------------------------------------------------------------*/
779 
780 
781 
782 IMPL_LINK( SwWrtShell, ExecFlyMac, void *, pFlyFmt )
783 {
784 	const SwFrmFmt *pFmt = pFlyFmt ? (SwFrmFmt*)pFlyFmt : GetFlyFrmFmt();
785 	ASSERT(pFmt, kein FrameFormat.);
786 	const SvxMacroItem &rFmtMac = pFmt->GetMacro();
787 
788 	if(rFmtMac.HasMacro(SW_EVENT_OBJECT_SELECT))
789 	{
790 		const SvxMacro &rMac = rFmtMac.GetMacro(SW_EVENT_OBJECT_SELECT);
791 		if( IsFrmSelected() )
792 			bLayoutMode = sal_True;
793 		CallChgLnk();
794 		ExecMacro( rMac );
795 	}
796 	return 0;
797 }
798 
799 
800 
801 long SwWrtShell::UpdateLayoutFrm(const Point *pPt, sal_Bool )
802 {
803 		// voerst Dummy
804 	SwFEShell::EndDrag( pPt, sal_False );
805 	fnDrag = &SwWrtShell::BeginFrmDrag;
806 	return 1;
807 }
808 
809 /*
810  * Handler fuer das Togglen der Modi. Liefern alten Mode zurueck.
811  */
812 
813 
814 
815 long SwWrtShell::ToggleAddMode()
816 {
817 	bAddMode ? LeaveAddMode(): EnterAddMode();
818 	Invalidate();
819 	return !bAddMode;
820 }
821 
822 
823 long SwWrtShell::ToggleBlockMode()
824 {
825 	bBlockMode ? LeaveBlockMode(): EnterBlockMode();
826 	Invalidate();
827 	return !bBlockMode;
828 }
829 
830 
831 long SwWrtShell::ToggleExtMode()
832 {
833 	bExtMode ? LeaveExtMode() : EnterExtMode();
834 	Invalidate();
835 	return !bExtMode;
836 }
837 /*
838  * Draggen im Standard Modus (Selektieren von Inhalt)
839  */
840 
841 
842 
843 long SwWrtShell::BeginDrag(const Point * /*pPt*/, sal_Bool )
844 {
845 	if(bSelWrd)
846 	{
847 		bInSelect = sal_True;
848 		if( !IsCrsrPtAtEnd() )
849 			SwapPam();
850 
851 		fnDrag = &SwWrtShell::ExtSelWrd;
852 		fnSetCrsr = &SwWrtShell::Ignore;
853 	}
854 	else if(bSelLn)
855 	{
856 		bInSelect = sal_True;
857 		fnDrag = &SwWrtShell::ExtSelLn;
858 		fnSetCrsr = &SwWrtShell::Ignore;
859 	}
860 	else
861 	{
862 		fnDrag = &SwWrtShell::Drag;
863 		SttSelect();
864 	}
865 
866 	return 1;
867 }
868 
869 
870 
871 long SwWrtShell::Drag(const Point *, sal_Bool )
872 {
873 	if( IsSelTblCells() )
874 		aSelTblLink.Call(this);
875 
876 	return 1;
877 }
878 
879 
880 
881 long SwWrtShell::EndDrag(const Point * /*pPt*/, sal_Bool )
882 {
883 	fnDrag = &SwWrtShell::BeginDrag;
884 	if( IsExtSel() )
885 		LeaveExtSel();
886 
887 	if( IsSelTblCells() )
888 		aSelTblLink.Call(this);
889 	EndSelect();
890 	return 1;
891 }
892 
893 // --> FME 2004-07-30 #i32329# Enhanced table selection
894 sal_Bool SwWrtShell::SelectTableRowCol( const Point& rPt, const Point* pEnd, bool bRowDrag )
895 {
896     MV_KONTEXT(this);
897     SttSelect();
898     if(SelTblRowCol( rPt, pEnd, bRowDrag ))
899     {
900         fnSetCrsr = &SwWrtShell::SetCrsrKillSel;
901         fnKillSel = &SwWrtShell::ResetSelect;
902         return sal_True;
903     }
904     return sal_False;
905 }
906 // <--
907 
908 /*------------------------------------------------------------------------
909  Beschreibung:  Selektion einer Tabellenzeile / Spalte
910 ------------------------------------------------------------------------*/
911 
912 sal_Bool SwWrtShell::SelectTableRow()
913 {
914 	if ( SelTblRow() )
915 	{
916 		fnSetCrsr = &SwWrtShell::SetCrsrKillSel;
917 		fnKillSel = &SwWrtShell::ResetSelect;
918 		return sal_True;
919 	}
920 	return sal_False;
921 }
922 
923 
924 
925 sal_Bool SwWrtShell::SelectTableCol()
926 {
927 	if ( SelTblCol() )
928 	{
929 		fnSetCrsr = &SwWrtShell::SetCrsrKillSel;
930 		fnKillSel = &SwWrtShell::ResetSelect;
931 		return sal_True;
932 	}
933 	return sal_False;
934 }
935 
936 sal_Bool SwWrtShell::SelectTableCell()
937 {
938     if ( SelTblBox() )
939     {
940         fnSetCrsr = &SwWrtShell::SetCrsrKillSel;
941         fnKillSel = &SwWrtShell::ResetSelect;
942         return sal_True;
943     }
944     return sal_False;
945 }
946 /*------------------------------------------------------------------------
947  Beschreibung:	  Prueft, ob eine Wortselektion vorliegt.
948 				  Gemaess den Regeln fuer intelligentes Cut / Paste
949 				  werden umgebende Spaces rausgeschnitten.
950  Return:		  Liefert Art der Wortselektion zurueck.
951 ------------------------------------------------------------------------*/
952 
953 
954 
955 int SwWrtShell::IntelligentCut(int nSelection, sal_Bool bCut)
956 {
957 		// kein intelligentes Drag and Drop bei Mehrfachselektion
958 		// es existieren mehrere Cursor, da ein zweiter bereits
959 		// an die Zielposition gesetzt wurde
960     if( IsAddMode() || !(nSelection & nsSelectionType::SEL_TXT) )
961 		return sal_False;
962 
963 	String sTxt;
964 	CharClass& rCC = GetAppCharClass();
965 
966 		// wenn das erste und das letzte Zeichen kein Wortzeichen ist,
967 		// ist kein Wort selektiert.
968 	sal_Unicode cPrev = GetChar(sal_False);
969 	sal_Unicode cNext = GetChar(sal_True, -1);
970     if( !cPrev || !cNext ||
971 		!rCC.isLetterNumeric( ( sTxt = cPrev), 0 ) ||
972 		!rCC.isLetterNumeric( ( sTxt = cNext), 0 ) )
973 		return NO_WORD;
974 
975 	cPrev = GetChar(sal_False, -1);
976 	cNext = GetChar(sal_True);
977 
978 	int cWord = NO_WORD;
979 		// ist ein Wort selektiert?
980 	if(!cWord && cPrev && cNext &&
981 		CH_TXTATR_BREAKWORD != cPrev && CH_TXTATR_INWORD != cPrev &&
982 		CH_TXTATR_BREAKWORD != cNext && CH_TXTATR_INWORD != cNext &&
983 		!rCC.isLetterNumeric( ( sTxt = cPrev), 0 ) &&
984 		!rCC.isLetterNumeric( ( sTxt = cNext), 0 ) )
985 	   cWord = WORD_NO_SPACE;
986 
987 	if(cWord == WORD_NO_SPACE && ' ' == cPrev )
988 	{
989 		cWord = WORD_SPACE_BEFORE;
990 			// Space davor loeschen
991 		if(bCut)
992 		{
993 			Push();
994 			if(IsCrsrPtAtEnd())
995 				SwapPam();
996 			ClearMark();
997 			SetMark();
998 			SwCrsrShell::Left(1,CRSR_SKIP_CHARS);
999 			SwFEShell::Delete();
1000 			Pop( sal_False );
1001 		}
1002 	}
1003 	else if(cWord == WORD_NO_SPACE && cNext == ' ')
1004 	{
1005 		cWord = WORD_SPACE_AFTER;
1006 			// Space dahinter loeschen
1007 		if(bCut) {
1008 			Push();
1009 			if(!IsCrsrPtAtEnd()) SwapPam();
1010 			ClearMark();
1011 			SetMark();
1012 			SwCrsrShell::Right(1,CRSR_SKIP_CHARS);
1013 			SwFEShell::Delete();
1014 			Pop( sal_False );
1015 		}
1016 	}
1017 	return cWord;
1018 }
1019 
1020 
1021 
1022 	// jump to the next / previous hyperlink - inside text and also
1023 	// on graphics
1024 sal_Bool SwWrtShell::SelectNextPrevHyperlink( sal_Bool bNext )
1025 {
1026 	StartAction();
1027 	sal_Bool bRet = SwCrsrShell::SelectNxtPrvHyperlink( bNext );
1028 	if( !bRet )
1029 	{
1030 		// will we have this feature?
1031 		EnterStdMode();
1032 		if( bNext )
1033 			SttEndDoc(sal_True);
1034 		else
1035 			SttEndDoc(sal_False);
1036 		bRet = SwCrsrShell::SelectNxtPrvHyperlink( bNext );
1037 	}
1038 	EndAction();
1039 
1040 	sal_Bool bCreateXSelection = sal_False;
1041 	const sal_Bool bFrmSelected = IsFrmSelected() || IsObjSelected();
1042 	if( IsSelection() )
1043 	{
1044 		if ( bFrmSelected )
1045 			UnSelectFrm();
1046 
1047 		// Funktionspointer fuer das Aufheben der Selektion setzen
1048 		// bei Cursor setzen
1049 		fnKillSel = &SwWrtShell::ResetSelect;
1050 		fnSetCrsr = &SwWrtShell::SetCrsrKillSel;
1051 		bCreateXSelection = sal_True;
1052 	}
1053 	else if( bFrmSelected )
1054 	{
1055 		EnterSelFrmMode();
1056 		bCreateXSelection = sal_True;
1057 	}
1058 	else if( (CNT_GRF | CNT_OLE ) & GetCntType() )
1059 	{
1060 		SelectObj( GetCharRect().Pos() );
1061 		EnterSelFrmMode();
1062 		bCreateXSelection = sal_True;
1063 	}
1064 
1065 	if( bCreateXSelection )
1066 		SwTransferable::CreateSelection( *this );
1067 
1068 	return bRet;
1069 }
1070 
1071 
1072 /* fuer den Erhalt der Selektion wird nach SetMark() der Cursor
1073  * nach links bewegt, damit er durch das Einfuegen von Text nicht
1074  * verschoben wird.  Da auf der CORE-Seite am aktuellen Cursor
1075  * eine bestehende Selektion aufgehoben wird, wird der Cursor auf
1076  * den Stack gepushed. Nach dem Verschieben werden sie wieder
1077  * zusammengefasst. */
1078 
1079 
1080 
1081 
1082