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