xref: /trunk/main/sw/source/ui/wrtsh/select.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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