Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <limits.h>
21 : #include <hintids.hxx>
22 : #include <sfx2/bindings.hxx>
23 : #include <svl/eitem.hxx>
24 : #include <svl/macitem.hxx>
25 : #include <unotools/charclass.hxx>
26 : #include <editeng/scripttypeitem.hxx>
27 : #include <cmdid.h>
28 : #include <view.hxx>
29 : #include <basesh.hxx>
30 : #include <wrtsh.hxx>
31 : #include <frmatr.hxx>
32 : #include <initui.hxx>
33 : #include <mdiexp.hxx>
34 : #include <fmtcol.hxx>
35 : #include <frmfmt.hxx>
36 : #include <swundo.hxx>
37 : #include <swevent.hxx>
38 : #include <swdtflvr.hxx>
39 : #include <crsskip.hxx>
40 : #include <doc.hxx>
41 : #include <wordcountdialog.hxx>
42 :
43 : namespace com { namespace sun { namespace star { namespace util {
44 : struct SearchOptions;
45 : } } } }
46 :
47 : using namespace ::com::sun::star::util;
48 :
49 : static long nStartDragX = 0, nStartDragY = 0;
50 : static bool bStartDrag = false;
51 :
52 0 : void SwWrtShell::Invalidate()
53 : {
54 : // to avoid making the slot volatile, invalidate it everytime if something could have been changed
55 : // this is still much cheaper than asking for the state every 200 ms (and avoid background processing)
56 0 : GetView().GetViewFrame()->GetBindings().Invalidate( FN_STAT_SELMODE );
57 0 : SwWordCountWrapper *pWrdCnt = (SwWordCountWrapper*)GetView().GetViewFrame()->GetChildWindow(SwWordCountWrapper::GetChildWindowId());
58 0 : if (pWrdCnt)
59 0 : pWrdCnt->UpdateCounts();
60 0 : }
61 :
62 0 : sal_Bool SwWrtShell::SelNearestWrd()
63 : {
64 0 : SwMvContext aMvContext(this);
65 0 : if( !IsInWrd() && !IsEndWrd() && !IsSttWrd() )
66 0 : PrvWrd();
67 0 : if( IsEndWrd() )
68 0 : Left(CRSR_SKIP_CELLS, sal_False, 1, sal_False );
69 0 : return SelWrd();
70 : }
71 :
72 0 : sal_Bool SwWrtShell::SelWrd(const Point *pPt, sal_Bool )
73 : {
74 : sal_Bool bRet;
75 : {
76 0 : SwMvContext aMvContext(this);
77 0 : SttSelect();
78 0 : bRet = SwCrsrShell::SelectWord( pPt );
79 : }
80 0 : EndSelect();
81 0 : if( bRet )
82 : {
83 0 : bSelWrd = sal_True;
84 0 : if(pPt)
85 0 : aStart = *pPt;
86 : }
87 0 : return bRet;
88 : }
89 :
90 0 : void SwWrtShell::SelSentence(const Point *pPt, sal_Bool )
91 : {
92 : {
93 0 : SwMvContext aMvContext(this);
94 0 : ClearMark();
95 0 : SwCrsrShell::GoStartSentence();
96 0 : SttSelect();
97 0 : SwCrsrShell::GoEndSentence();
98 : }
99 0 : EndSelect();
100 0 : if(pPt)
101 0 : aStart = *pPt;
102 0 : bSelLn = sal_True;
103 0 : bSelWrd = sal_False; // disable SelWord, otherwise no SelLine goes on
104 0 : }
105 :
106 0 : void SwWrtShell::SelPara(const Point *pPt, sal_Bool )
107 : {
108 : {
109 0 : SwMvContext aMvContext(this);
110 0 : ClearMark();
111 0 : SwCrsrShell::MovePara( fnParaCurr, fnParaStart );
112 0 : SttSelect();
113 0 : SwCrsrShell::MovePara( fnParaCurr, fnParaEnd );
114 : }
115 0 : EndSelect();
116 0 : if(pPt)
117 0 : aStart = *pPt;
118 0 : bSelLn = sal_False;
119 0 : bSelWrd = sal_False; // disable SelWord, otherwise no SelLine goes on
120 0 : }
121 :
122 0 : long SwWrtShell::SelAll()
123 : {
124 0 : const sal_Bool bLockedView = IsViewLocked();
125 0 : LockView( sal_True );
126 : {
127 0 : if(bBlockMode)
128 0 : LeaveBlockMode();
129 0 : SwMvContext aMvContext(this);
130 0 : sal_Bool bMoveTable = sal_False;
131 0 : SwPosition *pStartPos = 0;
132 0 : SwPosition *pEndPos = 0;
133 0 : SwShellCrsr* pTmpCrsr = 0;
134 0 : if( !HasWholeTabSelection() )
135 : {
136 0 : if ( IsSelection() && IsCrsrPtAtEnd() )
137 0 : SwapPam();
138 0 : pTmpCrsr = getShellCrsr( false );
139 0 : if( pTmpCrsr )
140 : {
141 0 : pStartPos = new SwPosition( *pTmpCrsr->GetPoint() );
142 0 : pEndPos = new SwPosition( *pTmpCrsr->GetMark() );
143 : }
144 0 : Push();
145 0 : bool bIsFullSel = !MoveSection( fnSectionCurr, fnSectionStart);
146 0 : SwapPam();
147 0 : bIsFullSel &= !MoveSection( fnSectionCurr, fnSectionEnd);
148 0 : Pop(sal_False);
149 0 : GoStart(sal_True, &bMoveTable, sal_False, !bIsFullSel);
150 : }
151 : else
152 : {
153 0 : EnterStdMode();
154 0 : SttEndDoc(sal_True);
155 : }
156 0 : SttSelect();
157 0 : GoEnd(sal_True, &bMoveTable);
158 :
159 0 : bool bStartsWithTable = StartsWithTable();
160 0 : if (bStartsWithTable)
161 : {
162 : // Disable table cursor to make sure getShellCrsr() returns m_pCurCrsr, not m_pTblCrsr.
163 0 : if (IsTableMode())
164 0 : TblCrsrToCursor();
165 : // Do the extended select all on m_pCurCrsr.
166 0 : ExtendedSelectAll(/*bFootnotes =*/ false);
167 : }
168 :
169 0 : SwDoc *pDoc = GetDoc();
170 0 : if ( pDoc )
171 : {
172 0 : pDoc->SetPrepareSelAll();
173 : }
174 :
175 0 : if( pStartPos )
176 : {
177 0 : pTmpCrsr = getShellCrsr( false );
178 0 : if( pTmpCrsr )
179 : {
180 : // Some special handling for sections (e.g. TOC) at the beginning of the document body
181 : // to avoid the selection of the first section
182 : // if the last selection was behind the first section or
183 : // if the last selection was already the first section
184 : // In this both cases we select to the end of document
185 0 : if( ( *pTmpCrsr->GetPoint() < *pEndPos ||
186 0 : ( *pStartPos == *pTmpCrsr->GetMark() &&
187 0 : *pEndPos == *pTmpCrsr->GetPoint() ) ) && !bStartsWithTable)
188 0 : SwCrsrShell::SttEndDoc(sal_False);
189 : }
190 0 : delete pStartPos;
191 0 : delete pEndPos;
192 0 : }
193 : }
194 0 : EndSelect();
195 0 : LockView( bLockedView );
196 0 : return 1;
197 : }
198 :
199 : // Desciption: Text search
200 :
201 0 : sal_uLong SwWrtShell::SearchPattern( const SearchOptions& rSearchOpt, sal_Bool bSearchInNotes,
202 : SwDocPositions eStt, SwDocPositions eEnd,
203 : FindRanges eFlags, int bReplace )
204 : {
205 : // no enhancement of existing selections
206 0 : if(!(eFlags & FND_IN_SEL))
207 0 : ClearMark();
208 0 : sal_Bool bCancel = sal_False;
209 0 : sal_uLong nRet = Find( rSearchOpt, bSearchInNotes, eStt, eEnd, bCancel, eFlags, bReplace );
210 0 : if(bCancel)
211 : {
212 0 : Undo(1);
213 0 : nRet = ULONG_MAX;
214 : }
215 0 : return nRet;
216 : }
217 :
218 : // Description: search for templates
219 :
220 0 : sal_uLong SwWrtShell::SearchTempl( const OUString &rTempl,
221 : SwDocPositions eStt, SwDocPositions eEnd,
222 : FindRanges eFlags, const OUString* pReplTempl )
223 : {
224 : // no enhancement of existing selections
225 0 : if(!(eFlags & FND_IN_SEL))
226 0 : ClearMark();
227 0 : SwTxtFmtColl *pColl = GetParaStyle(rTempl, SwWrtShell::GETSTYLE_CREATESOME);
228 0 : SwTxtFmtColl *pReplaceColl = 0;
229 0 : if( pReplTempl )
230 0 : pReplaceColl = GetParaStyle(*pReplTempl, SwWrtShell::GETSTYLE_CREATESOME );
231 :
232 0 : sal_Bool bCancel = sal_False;
233 0 : sal_uLong nRet = Find(pColl? *pColl: GetDfltTxtFmtColl(),
234 0 : eStt,eEnd, bCancel, eFlags, pReplaceColl);
235 0 : if(bCancel)
236 : {
237 0 : Undo(1);
238 0 : nRet = ULONG_MAX;
239 : }
240 0 : return nRet;
241 : }
242 :
243 : // search for attributes
244 :
245 0 : sal_uLong SwWrtShell::SearchAttr( const SfxItemSet& rFindSet, sal_Bool bNoColls,
246 : SwDocPositions eStart, SwDocPositions eEnde,
247 : FindRanges eFlags, const SearchOptions* pSearchOpt,
248 : const SfxItemSet* pReplaceSet )
249 : {
250 : // no enhancement of existing selections
251 0 : if (!(eFlags & FND_IN_SEL))
252 0 : ClearMark();
253 :
254 : // Searching
255 0 : sal_Bool bCancel = sal_False;
256 0 : sal_uLong nRet = Find( rFindSet, bNoColls, eStart, eEnde, bCancel, eFlags, pSearchOpt, pReplaceSet);
257 :
258 0 : if(bCancel)
259 : {
260 0 : Undo(1);
261 0 : nRet = ULONG_MAX;
262 : }
263 0 : return nRet;
264 : }
265 :
266 : // Selection modes
267 :
268 0 : void SwWrtShell::PushMode()
269 : {
270 0 : pModeStack = new ModeStack( pModeStack, bIns, bExtMode, bAddMode, bBlockMode );
271 0 : }
272 :
273 0 : void SwWrtShell::PopMode()
274 : {
275 0 : if ( 0 == pModeStack )
276 0 : return;
277 :
278 0 : if ( bExtMode && !pModeStack->bExt )
279 0 : LeaveExtMode();
280 0 : if ( bAddMode && !pModeStack->bAdd )
281 0 : LeaveAddMode();
282 0 : if ( bBlockMode && !pModeStack->bBlock )
283 0 : LeaveBlockMode();
284 0 : bIns = pModeStack->bIns;
285 :
286 0 : ModeStack *pTmp = pModeStack->pNext;
287 0 : delete pModeStack;
288 0 : pModeStack = pTmp;
289 : }
290 :
291 : // Two methodes for setting cursors: the first maps at the
292 : // eponymous methodes in the CursorShell, the second removes
293 : // all selections at first.
294 :
295 0 : long SwWrtShell::SetCrsr(const Point *pPt, sal_Bool bTextOnly)
296 : {
297 : // Remove a possibly present selection at the position
298 : // of the mouseclick
299 :
300 0 : if(!IsInSelect() && ChgCurrPam(*pPt)) {
301 0 : ClearMark();
302 : }
303 :
304 0 : return SwCrsrShell::SetCrsr(*pPt, bTextOnly);
305 : }
306 :
307 0 : long SwWrtShell::SetCrsrKillSel(const Point *pPt, sal_Bool bTextOnly )
308 : {
309 0 : SwActContext aActContext(this);
310 0 : ResetSelect(pPt,sal_False);
311 0 : return SwCrsrShell::SetCrsr(*pPt, bTextOnly);
312 : }
313 :
314 0 : void SwWrtShell::UnSelectFrm()
315 : {
316 : // Remove Frame selection with guaranteed invalid position
317 0 : Point aPt(LONG_MIN, LONG_MIN);
318 0 : SelectObj(aPt, 0);
319 0 : SwTransferable::ClearSelection( *this );
320 0 : }
321 :
322 : // Remove of all selections
323 :
324 0 : long SwWrtShell::ResetSelect(const Point *,sal_Bool)
325 : {
326 0 : if(IsSelFrmMode())
327 : {
328 0 : UnSelectFrm();
329 0 : LeaveSelFrmMode();
330 : }
331 : else
332 : {
333 : // SwActContext opens an Action -
334 : // to avoid problems in the basic process with the
335 : // shell switching, GetChgLnk().Call() may be called
336 : // after EndAction().
337 : {
338 0 : SwActContext aActContext(this);
339 0 : bSelWrd = bSelLn = sal_False;
340 0 : KillPams();
341 0 : ClearMark();
342 0 : fnKillSel = &SwWrtShell::Ignore;
343 0 : fnSetCrsr = &SwWrtShell::SetCrsr;
344 : }
345 :
346 : // After canceling of all selections an update of Attr-Controls
347 : // could be necessary.
348 0 : GetChgLnk().Call(this);
349 : }
350 0 : Invalidate();
351 0 : SwTransferable::ClearSelection( *this );
352 0 : return 1;
353 : }
354 :
355 : // Do nothing
356 :
357 0 : long SwWrtShell::Ignore(const Point *, sal_Bool ) {
358 0 : return 1;
359 : }
360 :
361 : // Begin of a selection process.
362 :
363 0 : void SwWrtShell::SttSelect()
364 : {
365 0 : if(bInSelect)
366 0 : return;
367 0 : if(!HasMark())
368 0 : SetMark();
369 0 : if( bBlockMode )
370 : {
371 0 : SwShellCrsr* pTmp = getShellCrsr( true );
372 0 : if( !pTmp->HasMark() )
373 0 : pTmp->SetMark();
374 : }
375 0 : fnKillSel = &SwWrtShell::Ignore;
376 0 : fnSetCrsr = &SwWrtShell::SetCrsr;
377 0 : bInSelect = sal_True;
378 0 : Invalidate();
379 0 : SwTransferable::CreateSelection( *this );
380 : }
381 :
382 : // End of a selection process.
383 :
384 0 : void SwWrtShell::EndSelect()
385 : {
386 0 : if(bInSelect && !bExtMode)
387 : {
388 0 : bInSelect = sal_False;
389 0 : if (bAddMode)
390 : {
391 0 : AddLeaveSelect(0, sal_False);
392 : }
393 : else
394 : {
395 0 : SttLeaveSelect(0, sal_False);
396 0 : fnSetCrsr = &SwWrtShell::SetCrsrKillSel;
397 0 : fnKillSel = &SwWrtShell::ResetSelect;
398 : }
399 : }
400 0 : SwWordCountWrapper *pWrdCnt = (SwWordCountWrapper*)GetView().GetViewFrame()->GetChildWindow(SwWordCountWrapper::GetChildWindowId());
401 0 : if (pWrdCnt)
402 0 : pWrdCnt->UpdateCounts();
403 0 : }
404 :
405 : // Methode to enhance a selecton word by word or line by line.
406 :
407 : inline bool operator<(const Point &rP1,const Point &rP2)
408 : {
409 : return rP1.Y() < rP2.Y() || (rP1.Y() == rP2.Y() && rP1.X() < rP2.X());
410 : }
411 :
412 0 : long SwWrtShell::ExtSelWrd(const Point *pPt, sal_Bool )
413 : {
414 0 : SwMvContext aMvContext(this);
415 0 : if( IsTableMode() )
416 0 : return 1;
417 :
418 : // Bug 66823: actual crsr has in additional mode no selection?
419 : // Then destroy the actual an go to prev, this will be expand
420 0 : if( !HasMark() && GoPrevCrsr() )
421 : {
422 0 : sal_Bool bHasMark = HasMark(); // thats wrong!
423 0 : GoNextCrsr();
424 0 : if( bHasMark )
425 : {
426 0 : DestroyCrsr();
427 0 : GoPrevCrsr();
428 : }
429 : }
430 :
431 : // check the direction of the selection with the new point
432 0 : sal_Bool bRet = sal_False, bMoveCrsr = sal_True, bToTop = sal_False;
433 0 : SwCrsrShell::SelectWord( &aStart ); // select the startword
434 0 : SwCrsrShell::Push(); // save the cursor
435 0 : SwCrsrShell::SetCrsr( *pPt ); // and check the direction
436 :
437 0 : switch( SwCrsrShell::CompareCursor( StackMkCurrPt ))
438 : {
439 0 : case -1: bToTop = sal_False; break;
440 0 : case 1: bToTop = sal_True; break;
441 0 : default: bMoveCrsr = sal_False; break;
442 : }
443 :
444 0 : SwCrsrShell::Pop( sal_False ); // retore the saved cursor
445 :
446 0 : if( bMoveCrsr )
447 : {
448 : // select to Top but cursor select to Bottom? or
449 : // select to Bottom but cursor select to Top? --> swap the cursor
450 0 : if( bToTop )
451 0 : SwapPam();
452 :
453 0 : SwCrsrShell::Push(); // save cur cursor
454 0 : if( SwCrsrShell::SelectWord( pPt )) // select the current word
455 : {
456 0 : if( bToTop )
457 0 : SwapPam();
458 0 : Combine();
459 0 : bRet = sal_True;
460 : }
461 : else
462 : {
463 0 : SwCrsrShell::Pop( sal_False );
464 0 : if( bToTop )
465 0 : SwapPam();
466 : }
467 : }
468 : else
469 0 : bRet = sal_True;
470 0 : return bRet;
471 : }
472 :
473 0 : long SwWrtShell::ExtSelLn(const Point *pPt, sal_Bool )
474 : {
475 0 : SwMvContext aMvContext(this);
476 0 : SwCrsrShell::SetCrsr(*pPt);
477 0 : if( IsTableMode() )
478 0 : return 1;
479 :
480 : // Bug 66823: actual crsr has in additional mode no selection?
481 : // Then destroy the actual an go to prev, this will be expand
482 0 : if( !HasMark() && GoPrevCrsr() )
483 : {
484 0 : sal_Bool bHasMark = HasMark(); // thats wrong!
485 0 : GoNextCrsr();
486 0 : if( bHasMark )
487 : {
488 0 : DestroyCrsr();
489 0 : GoPrevCrsr();
490 : }
491 : }
492 :
493 : // if applicable fit the selection to the "Mark"
494 0 : sal_Bool bToTop = !IsCrsrPtAtEnd();
495 0 : SwapPam();
496 :
497 : // The "Mark" has to be at the end or the beginning of the line.
498 0 : if( bToTop ? !IsEndSentence() : !IsStartSentence() )
499 : {
500 0 : if( bToTop )
501 : {
502 0 : if( !IsEndPara() )
503 0 : SwCrsrShell::Right(1,CRSR_SKIP_CHARS);
504 0 : SwCrsrShell::GoEndSentence();
505 : }
506 : else
507 0 : SwCrsrShell::GoStartSentence();
508 : }
509 0 : SwapPam();
510 :
511 0 : return bToTop ? SwCrsrShell::GoStartSentence() : SwCrsrShell::GoEndSentence();
512 : }
513 :
514 : // Back into the standard mode: no mode, no selections.
515 :
516 0 : void SwWrtShell::EnterStdMode()
517 : {
518 0 : if(bAddMode)
519 0 : LeaveAddMode();
520 0 : if(bBlockMode)
521 0 : LeaveBlockMode();
522 0 : bBlockMode = sal_False;
523 0 : bExtMode = sal_False;
524 0 : bInSelect = sal_False;
525 0 : if(IsSelFrmMode())
526 : {
527 0 : UnSelectFrm();
528 0 : LeaveSelFrmMode();
529 : }
530 : else
531 : {
532 : // SwActContext opens and action which has to be
533 : // closed prior to the call of
534 : // GetChgLnk().Call()
535 : {
536 0 : SwActContext aActContext(this);
537 0 : bSelWrd = bSelLn = sal_False;
538 0 : if( !IsRetainSelection() )
539 0 : KillPams();
540 0 : ClearMark();
541 0 : fnSetCrsr = &SwWrtShell::SetCrsrKillSel;
542 0 : fnKillSel = &SwWrtShell::ResetSelect;
543 : }
544 : }
545 0 : Invalidate();
546 0 : SwTransferable::ClearSelection( *this );
547 0 : }
548 :
549 : // Extended Mode
550 :
551 0 : void SwWrtShell::EnterExtMode()
552 : {
553 0 : if(bBlockMode)
554 : {
555 0 : LeaveBlockMode();
556 0 : KillPams();
557 0 : ClearMark();
558 : }
559 0 : bExtMode = sal_True;
560 0 : bAddMode = sal_False;
561 0 : bBlockMode = sal_False;
562 0 : SttSelect();
563 0 : }
564 :
565 0 : void SwWrtShell::LeaveExtMode()
566 : {
567 0 : bExtMode = sal_False;
568 0 : EndSelect();
569 0 : }
570 :
571 : // End of a selection; if the selection is empty,
572 : // ClearMark().
573 :
574 0 : long SwWrtShell::SttLeaveSelect(const Point *, sal_Bool )
575 : {
576 0 : if(SwCrsrShell::HasSelection() && !IsSelTblCells() && bClearMark) {
577 0 : return 0;
578 : }
579 0 : ClearMark();
580 0 : return 1;
581 : }
582 :
583 : // Leaving of the selection mode in additional mode
584 :
585 0 : long SwWrtShell::AddLeaveSelect(const Point *, sal_Bool )
586 : {
587 0 : if(IsTableMode()) LeaveAddMode();
588 0 : else if(SwCrsrShell::HasSelection())
589 0 : CreateCrsr();
590 0 : return 1;
591 : }
592 :
593 : // Additional Mode
594 :
595 0 : void SwWrtShell::EnterAddMode()
596 : {
597 0 : if(IsTableMode()) return;
598 0 : if(bBlockMode)
599 0 : LeaveBlockMode();
600 0 : fnKillSel = &SwWrtShell::Ignore;
601 0 : fnSetCrsr = &SwWrtShell::SetCrsr;
602 0 : bAddMode = sal_True;
603 0 : bBlockMode = sal_False;
604 0 : bExtMode = sal_False;
605 0 : if(SwCrsrShell::HasSelection())
606 0 : CreateCrsr();
607 0 : Invalidate();
608 : }
609 :
610 0 : void SwWrtShell::LeaveAddMode()
611 : {
612 0 : fnKillSel = &SwWrtShell::ResetSelect;
613 0 : fnSetCrsr = &SwWrtShell::SetCrsrKillSel;
614 0 : bAddMode = sal_False;
615 0 : Invalidate();
616 0 : }
617 :
618 : // Block Mode
619 :
620 0 : void SwWrtShell::EnterBlockMode()
621 : {
622 0 : bBlockMode = sal_False;
623 0 : EnterStdMode();
624 0 : bBlockMode = sal_True;
625 0 : CrsrToBlockCrsr();
626 0 : Invalidate();
627 0 : }
628 :
629 0 : void SwWrtShell::LeaveBlockMode()
630 : {
631 0 : bBlockMode = sal_False;
632 0 : BlockCrsrToCrsr();
633 0 : EndSelect();
634 0 : Invalidate();
635 0 : }
636 :
637 : // Insert mode
638 :
639 0 : void SwWrtShell::SetInsMode( sal_Bool bOn )
640 : {
641 0 : bIns = bOn;
642 0 : SwCrsrShell::SetOverwriteCrsr( !bIns );
643 0 : const SfxBoolItem aTmp( SID_ATTR_INSERT, bIns );
644 0 : GetView().GetViewFrame()->GetBindings().SetState( aTmp );
645 0 : StartAction();
646 0 : EndAction();
647 0 : Invalidate();
648 0 : }
649 : //Overwrite mode is incompatible with red-lining
650 0 : void SwWrtShell::SetRedlineModeAndCheckInsMode( sal_uInt16 eMode )
651 : {
652 0 : SetRedlineMode( eMode );
653 0 : if (IsRedlineOn())
654 0 : SetInsMode( true );
655 0 : }
656 :
657 : // Edit frame
658 :
659 0 : long SwWrtShell::BeginFrmDrag(const Point *pPt, sal_Bool)
660 : {
661 0 : fnDrag = &SwFEShell::Drag;
662 0 : if(bStartDrag)
663 : {
664 0 : Point aTmp( nStartDragX, nStartDragY );
665 0 : SwFEShell::BeginDrag( &aTmp, sal_False );
666 : }
667 : else
668 0 : SwFEShell::BeginDrag( pPt, sal_False );
669 0 : return 1;
670 : }
671 :
672 0 : void SwWrtShell::EnterSelFrmMode(const Point *pPos)
673 : {
674 0 : if(pPos)
675 : {
676 0 : nStartDragX = pPos->X();
677 0 : nStartDragY = pPos->Y();
678 0 : bStartDrag = true;
679 : }
680 0 : bLayoutMode = sal_True;
681 0 : HideCrsr();
682 :
683 : // equal call of BeginDrag in the SwFEShell
684 0 : fnDrag = &SwWrtShell::BeginFrmDrag;
685 0 : fnEndDrag = &SwWrtShell::UpdateLayoutFrm;
686 0 : SwBaseShell::SetFrmMode( FLY_DRAG_START, this );
687 0 : Invalidate();
688 0 : }
689 :
690 0 : void SwWrtShell::LeaveSelFrmMode()
691 : {
692 0 : fnDrag = &SwWrtShell::BeginDrag;
693 0 : fnEndDrag = &SwWrtShell::EndDrag;
694 0 : bLayoutMode = sal_False;
695 0 : bStartDrag = false;
696 0 : Edit();
697 0 : SwBaseShell::SetFrmMode( FLY_DRAG_END, this );
698 0 : Invalidate();
699 0 : }
700 :
701 : // Description: execute framebound macro
702 :
703 0 : IMPL_LINK( SwWrtShell, ExecFlyMac, void *, pFlyFmt )
704 : {
705 0 : const SwFrmFmt *pFmt = pFlyFmt ? (SwFrmFmt*)pFlyFmt : GetFlyFrmFmt();
706 : OSL_ENSURE(pFmt, "no frame format");
707 0 : const SvxMacroItem &rFmtMac = pFmt->GetMacro();
708 :
709 0 : if(rFmtMac.HasMacro(SW_EVENT_OBJECT_SELECT))
710 : {
711 0 : const SvxMacro &rMac = rFmtMac.GetMacro(SW_EVENT_OBJECT_SELECT);
712 0 : if( IsFrmSelected() )
713 0 : bLayoutMode = sal_True;
714 0 : CallChgLnk();
715 0 : ExecMacro( rMac );
716 : }
717 0 : return 0;
718 : }
719 :
720 0 : long SwWrtShell::UpdateLayoutFrm(const Point *pPt, sal_Bool )
721 : {
722 : // still a dummy
723 0 : SwFEShell::EndDrag( pPt, sal_False );
724 0 : fnDrag = &SwWrtShell::BeginFrmDrag;
725 0 : return 1;
726 : }
727 :
728 : // Handler for toggling the modes. Returns back the old mode.
729 :
730 0 : bool SwWrtShell::ToggleAddMode()
731 : {
732 0 : bAddMode ? LeaveAddMode(): EnterAddMode();
733 0 : Invalidate();
734 0 : return !bAddMode;
735 : }
736 :
737 0 : bool SwWrtShell::ToggleBlockMode()
738 : {
739 0 : bBlockMode ? LeaveBlockMode(): EnterBlockMode();
740 0 : Invalidate();
741 0 : return !bBlockMode;
742 : }
743 :
744 0 : bool SwWrtShell::ToggleExtMode()
745 : {
746 0 : bExtMode ? LeaveExtMode() : EnterExtMode();
747 0 : Invalidate();
748 0 : return !bExtMode;
749 : }
750 :
751 : // Dragging in standard mode (Selecting of content)
752 :
753 0 : long SwWrtShell::BeginDrag(const Point * /*pPt*/, sal_Bool )
754 : {
755 0 : if(bSelWrd)
756 : {
757 0 : bInSelect = sal_True;
758 0 : if( !IsCrsrPtAtEnd() )
759 0 : SwapPam();
760 :
761 0 : fnDrag = &SwWrtShell::ExtSelWrd;
762 0 : fnSetCrsr = &SwWrtShell::Ignore;
763 : }
764 0 : else if(bSelLn)
765 : {
766 0 : bInSelect = sal_True;
767 0 : fnDrag = &SwWrtShell::ExtSelLn;
768 0 : fnSetCrsr = &SwWrtShell::Ignore;
769 : }
770 : else
771 : {
772 0 : fnDrag = &SwWrtShell::Drag;
773 0 : SttSelect();
774 : }
775 :
776 0 : return 1;
777 : }
778 :
779 0 : long SwWrtShell::Drag(const Point *, sal_Bool )
780 : {
781 0 : if( IsSelTblCells() )
782 0 : aSelTblLink.Call(this);
783 :
784 0 : return 1;
785 : }
786 :
787 0 : long SwWrtShell::EndDrag(const Point * /*pPt*/, sal_Bool )
788 : {
789 0 : fnDrag = &SwWrtShell::BeginDrag;
790 0 : if( IsExtSel() )
791 0 : LeaveExtSel();
792 :
793 0 : if( IsSelTblCells() )
794 0 : aSelTblLink.Call(this);
795 0 : EndSelect();
796 0 : return 1;
797 : }
798 :
799 : // #i32329# Enhanced table selection
800 0 : sal_Bool SwWrtShell::SelectTableRowCol( const Point& rPt, const Point* pEnd, bool bRowDrag )
801 : {
802 0 : SwMvContext aMvContext(this);
803 0 : SttSelect();
804 0 : if(SelTblRowCol( rPt, pEnd, bRowDrag ))
805 : {
806 0 : fnSetCrsr = &SwWrtShell::SetCrsrKillSel;
807 0 : fnKillSel = &SwWrtShell::ResetSelect;
808 0 : return sal_True;
809 : }
810 0 : return sal_False;
811 : }
812 :
813 : // Description: Selection of a table line or column
814 :
815 0 : sal_Bool SwWrtShell::SelectTableRow()
816 : {
817 0 : if ( SelTblRow() )
818 : {
819 0 : fnSetCrsr = &SwWrtShell::SetCrsrKillSel;
820 0 : fnKillSel = &SwWrtShell::ResetSelect;
821 0 : return sal_True;
822 : }
823 0 : return sal_False;
824 : }
825 :
826 0 : sal_Bool SwWrtShell::SelectTableCol()
827 : {
828 0 : if ( SelTblCol() )
829 : {
830 0 : fnSetCrsr = &SwWrtShell::SetCrsrKillSel;
831 0 : fnKillSel = &SwWrtShell::ResetSelect;
832 0 : return sal_True;
833 : }
834 0 : return sal_False;
835 : }
836 :
837 0 : sal_Bool SwWrtShell::SelectTableCell()
838 : {
839 0 : if ( SelTblBox() )
840 : {
841 0 : fnSetCrsr = &SwWrtShell::SetCrsrKillSel;
842 0 : fnKillSel = &SwWrtShell::ResetSelect;
843 0 : return sal_True;
844 : }
845 0 : return sal_False;
846 : }
847 :
848 : // Description: Check if a word selection is present.
849 : // According to the rules for intelligent cut / paste
850 : // surrounding spaces are cut out.
851 : // Return: Delivers the type of the word selection.
852 :
853 0 : int SwWrtShell::IntelligentCut(int nSelection, sal_Bool bCut)
854 : {
855 : // On multiple selection no intelligent drag and drop
856 : // there are multiple cursors, since a second was placed
857 : // already at the target postion.
858 0 : if( IsAddMode() || !(nSelection & nsSelectionType::SEL_TXT) )
859 0 : return sal_False;
860 :
861 0 : OUString sTxt;
862 0 : CharClass& rCC = GetAppCharClass();
863 :
864 : // If the first character is no word character,
865 : // no word selected.
866 0 : sal_Unicode cPrev = GetChar(sal_False);
867 0 : sal_Unicode cNext = GetChar(sal_True, -1);
868 0 : if( !cPrev || !cNext ||
869 0 : !rCC.isLetterNumeric( ( sTxt = OUString(cPrev) ), 0 ) ||
870 0 : !rCC.isLetterNumeric( ( sTxt = OUString(cNext) ), 0 ) )
871 0 : return NO_WORD;
872 :
873 0 : cPrev = GetChar(sal_False, -1);
874 0 : cNext = GetChar(sal_True);
875 :
876 0 : int cWord = NO_WORD;
877 : // is a word seleced?
878 0 : if(!cWord && cPrev && cNext &&
879 0 : CH_TXTATR_BREAKWORD != cPrev && CH_TXTATR_INWORD != cPrev &&
880 0 : CH_TXTATR_BREAKWORD != cNext && CH_TXTATR_INWORD != cNext &&
881 0 : !rCC.isLetterNumeric( ( sTxt = OUString(cPrev) ), 0 ) &&
882 0 : !rCC.isLetterNumeric( ( sTxt = OUString(cNext) ), 0 ) )
883 0 : cWord = WORD_NO_SPACE;
884 :
885 0 : if(cWord == WORD_NO_SPACE && ' ' == cPrev )
886 : {
887 0 : cWord = WORD_SPACE_BEFORE;
888 : // delete the space before
889 0 : if(bCut)
890 : {
891 0 : Push();
892 0 : if(IsCrsrPtAtEnd())
893 0 : SwapPam();
894 0 : ClearMark();
895 0 : SetMark();
896 0 : SwCrsrShell::Left(1,CRSR_SKIP_CHARS);
897 0 : SwFEShell::Delete();
898 0 : Pop( sal_False );
899 : }
900 : }
901 0 : else if(cWord == WORD_NO_SPACE && cNext == ' ')
902 : {
903 0 : cWord = WORD_SPACE_AFTER;
904 : // delete the space behind
905 0 : if(bCut) {
906 0 : Push();
907 0 : if(!IsCrsrPtAtEnd()) SwapPam();
908 0 : ClearMark();
909 0 : SetMark();
910 0 : SwCrsrShell::Right(1,CRSR_SKIP_CHARS);
911 0 : SwFEShell::Delete();
912 0 : Pop( sal_False );
913 : }
914 : }
915 0 : return cWord;
916 : }
917 :
918 : // jump to the next / previous hyperlink - inside text and also
919 : // on graphics
920 0 : bool SwWrtShell::SelectNextPrevHyperlink( bool bNext )
921 : {
922 0 : StartAction();
923 0 : bool bRet = SwCrsrShell::SelectNxtPrvHyperlink( bNext );
924 0 : if( !bRet )
925 : {
926 : // will we have this feature?
927 0 : EnterStdMode();
928 0 : if( bNext )
929 0 : SttEndDoc(sal_True);
930 : else
931 0 : SttEndDoc(sal_False);
932 0 : bRet = SwCrsrShell::SelectNxtPrvHyperlink( bNext );
933 : }
934 0 : EndAction();
935 :
936 0 : bool bCreateXSelection = false;
937 0 : const bool bFrmSelected = IsFrmSelected() || IsObjSelected();
938 0 : if( IsSelection() )
939 : {
940 0 : if ( bFrmSelected )
941 0 : UnSelectFrm();
942 :
943 : // Set the function pointer for the canceling of the selection
944 : // set at cursor
945 0 : fnKillSel = &SwWrtShell::ResetSelect;
946 0 : fnSetCrsr = &SwWrtShell::SetCrsrKillSel;
947 0 : bCreateXSelection = true;
948 : }
949 0 : else if( bFrmSelected )
950 : {
951 0 : EnterSelFrmMode();
952 0 : bCreateXSelection = true;
953 : }
954 0 : else if( (CNT_GRF | CNT_OLE ) & GetCntType() )
955 : {
956 0 : SelectObj( GetCharRect().Pos() );
957 0 : EnterSelFrmMode();
958 0 : bCreateXSelection = true;
959 : }
960 :
961 0 : if( bCreateXSelection )
962 0 : SwTransferable::CreateSelection( *this );
963 :
964 0 : return bRet;
965 0 : }
966 :
967 : // For the preservation of the selection the cursor will be moved left
968 : // after SetMark(), so that the cursor is not moved by inserting text.
969 : // Because a present selection at the CORE page is cleared at the
970 : // current cursor position, the cursor will be pushed on the stack.
971 : // After moving, they will again resummarized.
972 :
973 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|