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