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