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