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