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
Invalidate()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
SelNearestWrd()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
SelWrd(const Point * pPt,sal_Bool)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
SelSentence(const Point * pPt,sal_Bool)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
SelPara(const Point * pPt,sal_Bool)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
SelAll()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
SearchPattern(const SearchOptions & rSearchOpt,sal_Bool bSearchInNotes,SwDocPositions eStt,SwDocPositions eEnd,FindRanges eFlags,int bReplace)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
SearchTempl(const String & rTempl,SwDocPositions eStt,SwDocPositions eEnd,FindRanges eFlags,const String * pReplTempl)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
SearchAttr(const SfxItemSet & rFindSet,sal_Bool bNoColls,SwDocPositions eStart,SwDocPositions eEnde,FindRanges eFlags,const SearchOptions * pSearchOpt,const SfxItemSet * pReplaceSet)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
PushMode()277 void SwWrtShell::PushMode()
278 {
279 pModeStack = new ModeStack( pModeStack, bIns, bExtMode, bAddMode, bBlockMode );
280 }
281
282
283
PopMode()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
SetCrsr(const Point * pPt,sal_Bool bTextOnly)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
SetCrsrKillSel(const Point * pPt,sal_Bool bTextOnly)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
UnSelectFrm()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
ResetSelect(const Point *,sal_Bool)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 */
Ignore(const Point *,sal_Bool)386 long SwWrtShell::Ignore(const Point *, sal_Bool ) {
387 return 1;
388 }
389
390 /*
391 * Start eines Selektionsvorganges.
392 */
393
394
395
SttSelect()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
EndSelect()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
operator <(const Point & rP1,const Point & rP2)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
ExtSelWrd(const Point * pPt,sal_Bool)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
ExtSelLn(const Point * pPt,sal_Bool)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
EnterStdMode()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
EnterExtMode()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
LeaveExtMode()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
SttLeaveSelect(const Point *,sal_Bool)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
AddLeaveSelect(const Point *,sal_Bool)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
EnterAddMode()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
LeaveAddMode()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
EnterBlockMode()677 void SwWrtShell::EnterBlockMode()
678 {
679 bBlockMode = sal_False;
680 EnterStdMode();
681 bBlockMode = sal_True;
682 CrsrToBlockCrsr();
683 Invalidate();
684 }
685
686
687
LeaveBlockMode()688 void SwWrtShell::LeaveBlockMode()
689 {
690 bBlockMode = sal_False;
691 BlockCrsrToCrsr();
692 EndSelect();
693 Invalidate();
694 }
695
696 // Einfuegemodus
697
698
699
SetInsMode(sal_Bool bOn)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
SetRedlineModeAndCheckInsMode(sal_uInt16 eMode)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
BeginFrmDrag(const Point * pPt,sal_Bool)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
EnterSelFrmMode(const Point * pPos)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
LeaveSelFrmMode()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
IMPL_LINK(SwWrtShell,ExecFlyMac,void *,pFlyFmt)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
UpdateLayoutFrm(const Point * pPt,sal_Bool)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
ToggleAddMode()807 long SwWrtShell::ToggleAddMode()
808 {
809 bAddMode ? LeaveAddMode(): EnterAddMode();
810 Invalidate();
811 return !bAddMode;
812 }
813
814
ToggleBlockMode()815 long SwWrtShell::ToggleBlockMode()
816 {
817 bBlockMode ? LeaveBlockMode(): EnterBlockMode();
818 Invalidate();
819 return !bBlockMode;
820 }
821
822
ToggleExtMode()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
BeginDrag(const Point *,sal_Bool)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
Drag(const Point *,sal_Bool)863 long SwWrtShell::Drag(const Point *, sal_Bool )
864 {
865 if( IsSelTblCells() )
866 aSelTblLink.Call(this);
867
868 return 1;
869 }
870
871
872
EndDrag(const Point *,sal_Bool)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
SelectTableRowCol(const Point & rPt,const Point * pEnd,bool bRowDrag)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
SelectTableRow()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
SelectTableCol()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
SelectTableCell()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
IntelligentCut(int nSelection,sal_Bool bCut)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
SelectNextPrevHyperlink(sal_Bool bNext)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