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