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