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