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