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