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> // fuer 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 sal_Bool bStartDrag = sal_False;
52 :
53 22 : 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 22 : GetView().GetViewFrame()->GetBindings().Invalidate( FN_STAT_SELMODE );
58 22 : SwWordCountWrapper *pWrdCnt = (SwWordCountWrapper*)GetView().GetViewFrame()->GetChildWindow(SwWordCountWrapper::GetChildWindowId());
59 22 : if (pWrdCnt)
60 0 : pWrdCnt->UpdateCounts();
61 22 : }
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; // SelWord abschalten, sonst geht kein SelLine weiter
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; // SelWord abschalten, sonst geht kein SelLine weiter
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 : /*------------------------------------------------------------------------
187 : Beschreibung: Textsuche
188 : ------------------------------------------------------------------------*/
189 :
190 :
191 0 : sal_uLong SwWrtShell::SearchPattern( const SearchOptions& rSearchOpt, sal_Bool bSearchInNotes,
192 : SwDocPositions eStt, SwDocPositions eEnd,
193 : FindRanges eFlags, int bReplace )
194 : {
195 : // keine Erweiterung bestehender Selektionen
196 0 : if(!(eFlags & FND_IN_SEL))
197 0 : ClearMark();
198 0 : sal_Bool bCancel = sal_False;
199 0 : sal_uLong nRet = Find( rSearchOpt, bSearchInNotes, eStt, eEnd, bCancel, eFlags, bReplace );
200 0 : if(bCancel)
201 : {
202 0 : Undo(1);
203 0 : nRet = ULONG_MAX;
204 : }
205 0 : return nRet;
206 : }
207 : /*------------------------------------------------------------------------
208 : Beschreibung: Suche nach Vorlagen
209 : ------------------------------------------------------------------------*/
210 :
211 :
212 :
213 0 : sal_uLong SwWrtShell::SearchTempl( const String &rTempl,
214 : SwDocPositions eStt, SwDocPositions eEnd,
215 : FindRanges eFlags, const String* pReplTempl )
216 : {
217 : // keine Erweiterung bestehender Selektionen
218 0 : if(!(eFlags & FND_IN_SEL))
219 0 : ClearMark();
220 0 : SwTxtFmtColl *pColl = GetParaStyle(rTempl, SwWrtShell::GETSTYLE_CREATESOME);
221 0 : SwTxtFmtColl *pReplaceColl = 0;
222 0 : if( pReplTempl )
223 0 : pReplaceColl = GetParaStyle(*pReplTempl, SwWrtShell::GETSTYLE_CREATESOME );
224 :
225 0 : sal_Bool bCancel = sal_False;
226 0 : sal_uLong nRet = Find(pColl? *pColl: GetDfltTxtFmtColl(),
227 0 : eStt,eEnd, bCancel, eFlags, pReplaceColl);
228 0 : if(bCancel)
229 : {
230 0 : Undo(1);
231 0 : nRet = ULONG_MAX;
232 : }
233 0 : return nRet;
234 : }
235 :
236 : // Suche nach Attributen ----------------------------------------------------
237 :
238 :
239 :
240 0 : sal_uLong SwWrtShell::SearchAttr( const SfxItemSet& rFindSet, sal_Bool bNoColls,
241 : SwDocPositions eStart, SwDocPositions eEnde,
242 : FindRanges eFlags, const SearchOptions* pSearchOpt,
243 : const SfxItemSet* pReplaceSet )
244 : {
245 : // Keine Erweiterung bestehender Selektionen
246 0 : if (!(eFlags & FND_IN_SEL))
247 0 : ClearMark();
248 :
249 : // Suchen
250 0 : sal_Bool bCancel = sal_False;
251 0 : sal_uLong nRet = Find( rFindSet, bNoColls, eStart, eEnde, bCancel, eFlags, pSearchOpt, pReplaceSet);
252 :
253 0 : if(bCancel)
254 : {
255 0 : Undo(1);
256 0 : nRet = ULONG_MAX;
257 : }
258 0 : return nRet;
259 : }
260 :
261 : // ---------- Selektionsmodi ----------
262 :
263 :
264 :
265 0 : void SwWrtShell::PushMode()
266 : {
267 0 : pModeStack = new ModeStack( pModeStack, bIns, bExtMode, bAddMode, bBlockMode );
268 0 : }
269 :
270 :
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 : /*
291 : * Zwei Methoden fuer das Cursorsetzen; die erste mappt auf die
292 : * gleichnamige Methoden an der CursorShell, die zweite hebt
293 : * zuerst alle Selektionen auf.
294 : */
295 :
296 :
297 :
298 0 : long SwWrtShell::SetCrsr(const Point *pPt, sal_Bool bTextOnly)
299 : {
300 : /*
301 : * eine gfs. bestehende Selektion an der Position des
302 : * Mausklicks aufheben
303 : */
304 0 : if(!IsInSelect() && ChgCurrPam(*pPt)) {
305 0 : ClearMark();
306 : }
307 :
308 0 : return SwCrsrShell::SetCrsr(*pPt, bTextOnly);
309 : }
310 :
311 :
312 0 : long SwWrtShell::SetCrsrKillSel(const Point *pPt, sal_Bool bTextOnly )
313 : {
314 0 : SwActContext aActContext(this);
315 0 : ResetSelect(pPt,sal_False);
316 0 : return SwCrsrShell::SetCrsr(*pPt, bTextOnly);
317 : }
318 :
319 :
320 :
321 0 : void SwWrtShell::UnSelectFrm()
322 : {
323 : // Rahmenselektion aufheben mit garantiert ungueltiger Position
324 0 : Point aPt(LONG_MIN, LONG_MIN);
325 0 : SelectObj(aPt, 0);
326 0 : SwTransferable::ClearSelection( *this );
327 0 : }
328 :
329 : /*
330 : * Aufheben aller Selektionen
331 : */
332 :
333 :
334 :
335 7 : long SwWrtShell::ResetSelect(const Point *,sal_Bool)
336 : {
337 7 : if(IsSelFrmMode())
338 : {
339 0 : UnSelectFrm();
340 0 : LeaveSelFrmMode();
341 : }
342 : else
343 : {
344 : /* SwActContext macht eine Action auf -
345 : um im Basicablauf keine Probleme mit der
346 : Shellumschaltung zu bekommen, darf
347 : GetChgLnk().Call() erst nach
348 : EndAction() gerufen werden.
349 : */
350 : {
351 7 : SwActContext aActContext(this);
352 7 : bSelWrd = bSelLn = sal_False;
353 7 : KillPams();
354 7 : ClearMark();
355 7 : fnKillSel = &SwWrtShell::Ignore;
356 7 : fnSetCrsr = &SwWrtShell::SetCrsr;
357 : }
358 : /*
359 : * nach dem Aufheben aller Selektionen koennte ein Update der
360 : * Attr-Controls notwendig sein.
361 : */
362 7 : GetChgLnk().Call(this);
363 : }
364 7 : Invalidate();
365 7 : SwTransferable::ClearSelection( *this );
366 7 : return 1;
367 : }
368 :
369 :
370 :
371 : /*
372 : * tue nichts
373 : */
374 0 : long SwWrtShell::Ignore(const Point *, sal_Bool ) {
375 0 : return 1;
376 : }
377 :
378 : /*
379 : * Start eines Selektionsvorganges.
380 : */
381 :
382 :
383 :
384 0 : void SwWrtShell::SttSelect()
385 : {
386 0 : if(bInSelect)
387 0 : return;
388 0 : if(!HasMark())
389 0 : SetMark();
390 0 : if( bBlockMode )
391 : {
392 0 : SwShellCrsr* pTmp = getShellCrsr( true );
393 0 : if( !pTmp->HasMark() )
394 0 : pTmp->SetMark();
395 : }
396 0 : fnKillSel = &SwWrtShell::Ignore;
397 0 : fnSetCrsr = &SwWrtShell::SetCrsr;
398 0 : bInSelect = sal_True;
399 0 : Invalidate();
400 0 : SwTransferable::CreateSelection( *this );
401 : }
402 : /*
403 : * Ende eines Selektionsvorganges.
404 : */
405 :
406 :
407 :
408 7 : void SwWrtShell::EndSelect()
409 : {
410 7 : if(bInSelect && !bExtMode)
411 : {
412 0 : bInSelect = sal_False;
413 0 : if (bAddMode)
414 : {
415 0 : AddLeaveSelect(0, sal_False);
416 : }
417 : else
418 : {
419 0 : SttLeaveSelect(0, sal_False);
420 0 : fnSetCrsr = &SwWrtShell::SetCrsrKillSel;
421 0 : fnKillSel = &SwWrtShell::ResetSelect;
422 : }
423 : }
424 7 : SwWordCountWrapper *pWrdCnt = (SwWordCountWrapper*)GetView().GetViewFrame()->GetChildWindow(SwWordCountWrapper::GetChildWindowId());
425 7 : if (pWrdCnt)
426 0 : pWrdCnt->UpdateCounts();
427 7 : }
428 : /* Methode, um eine bestehende wortweise oder zeilenweise Selektion
429 : * zu erweitern.
430 : */
431 :
432 : inline sal_Bool operator<(const Point &rP1,const Point &rP2)
433 : {
434 : return rP1.Y() < rP2.Y() || (rP1.Y() == rP2.Y() && rP1.X() < rP2.X());
435 : }
436 :
437 :
438 :
439 0 : long SwWrtShell::ExtSelWrd(const Point *pPt, sal_Bool )
440 : {
441 0 : SwMvContext aMvContext(this);
442 0 : if( IsTableMode() )
443 0 : return 1;
444 :
445 : // Bug 66823: actual crsr has in additional mode no selection?
446 : // Then destroy the actual an go to prev, this will be expand
447 0 : if( !HasMark() && GoPrevCrsr() )
448 : {
449 0 : sal_Bool bHasMark = HasMark(); // thats wrong!
450 0 : GoNextCrsr();
451 0 : if( bHasMark )
452 : {
453 0 : DestroyCrsr();
454 0 : GoPrevCrsr();
455 : }
456 : }
457 :
458 : // check the direction of the selection with the new point
459 0 : sal_Bool bRet = sal_False, bMoveCrsr = sal_True, bToTop = sal_False;
460 0 : SwCrsrShell::SelectWord( &aStart ); // select the startword
461 0 : SwCrsrShell::Push(); // save the cursor
462 0 : SwCrsrShell::SetCrsr( *pPt ); // and check the direction
463 :
464 0 : switch( SwCrsrShell::CompareCursor( StackMkCurrPt ))
465 : {
466 0 : case -1: bToTop = sal_False; break;
467 0 : case 1: bToTop = sal_True; break;
468 0 : default: bMoveCrsr = sal_False; break;
469 : }
470 :
471 0 : SwCrsrShell::Pop( sal_False ); // retore the saved cursor
472 :
473 0 : if( bMoveCrsr )
474 : {
475 : // select to Top but cursor select to Bottom? or
476 : // select to Bottom but cursor select to Top? --> swap the cursor
477 0 : if( bToTop )
478 0 : SwapPam();
479 :
480 0 : SwCrsrShell::Push(); // save cur cursor
481 0 : if( SwCrsrShell::SelectWord( pPt )) // select the current word
482 : {
483 0 : if( bToTop )
484 0 : SwapPam();
485 0 : Combine();
486 0 : bRet = sal_True;
487 : }
488 : else
489 : {
490 0 : SwCrsrShell::Pop( sal_False );
491 0 : if( bToTop )
492 0 : SwapPam();
493 : }
494 : }
495 : else
496 0 : bRet = sal_True;
497 0 : return bRet;
498 : }
499 :
500 :
501 0 : long SwWrtShell::ExtSelLn(const Point *pPt, sal_Bool )
502 : {
503 0 : SwMvContext aMvContext(this);
504 0 : SwCrsrShell::SetCrsr(*pPt);
505 0 : if( IsTableMode() )
506 0 : return 1;
507 :
508 : // Bug 66823: actual crsr has in additional mode no selection?
509 : // Then destroy the actual an go to prev, this will be expand
510 0 : if( !HasMark() && GoPrevCrsr() )
511 : {
512 0 : sal_Bool bHasMark = HasMark(); // thats wrong!
513 0 : GoNextCrsr();
514 0 : if( bHasMark )
515 : {
516 0 : DestroyCrsr();
517 0 : GoPrevCrsr();
518 : }
519 : }
520 :
521 : // ggfs. den Mark der Selektion anpassen
522 0 : sal_Bool bToTop = !IsCrsrPtAtEnd();
523 0 : SwapPam();
524 :
525 : // der "Mark" muss am Zeilenende/-anfang stehen
526 0 : if( bToTop ? !IsEndSentence() : !IsStartSentence() )
527 : {
528 0 : if( bToTop )
529 : {
530 0 : if( !IsEndPara() )
531 0 : SwCrsrShell::Right(1,CRSR_SKIP_CHARS);
532 0 : SwCrsrShell::GoEndSentence();
533 : }
534 : else
535 0 : SwCrsrShell::GoStartSentence();
536 : }
537 0 : SwapPam();
538 :
539 0 : return bToTop ? SwCrsrShell::GoStartSentence() : SwCrsrShell::GoEndSentence();
540 : }
541 :
542 :
543 : /*
544 : * zurueck in den Standard Mode: kein Mode, keine Selektionen.
545 : */
546 :
547 15 : void SwWrtShell::EnterStdMode()
548 : {
549 15 : if(bAddMode)
550 0 : LeaveAddMode();
551 15 : if(bBlockMode)
552 0 : LeaveBlockMode();
553 15 : bBlockMode = sal_False;
554 15 : bExtMode = sal_False;
555 15 : bInSelect = sal_False;
556 15 : if(IsSelFrmMode())
557 : {
558 0 : UnSelectFrm();
559 0 : LeaveSelFrmMode();
560 : }
561 : else
562 : {
563 : /* SwActContext opens and action which has to be
564 : closed prior to the call of
565 : GetChgLnk().Call()
566 : */
567 : {
568 15 : SwActContext aActContext(this);
569 15 : bSelWrd = bSelLn = sal_False;
570 15 : if( !IsRetainSelection() )
571 15 : KillPams();
572 15 : ClearMark();
573 15 : fnSetCrsr = &SwWrtShell::SetCrsrKillSel;
574 15 : fnKillSel = &SwWrtShell::ResetSelect;
575 : }
576 : }
577 15 : Invalidate();
578 15 : SwTransferable::ClearSelection( *this );
579 15 : }
580 :
581 : /*
582 : * Extended Mode
583 : */
584 :
585 :
586 :
587 0 : void SwWrtShell::EnterExtMode()
588 : {
589 0 : if(bBlockMode)
590 : {
591 0 : LeaveBlockMode();
592 0 : KillPams();
593 0 : ClearMark();
594 : }
595 0 : bExtMode = sal_True;
596 0 : bAddMode = sal_False;
597 0 : bBlockMode = sal_False;
598 0 : SttSelect();
599 0 : }
600 :
601 :
602 :
603 0 : void SwWrtShell::LeaveExtMode()
604 : {
605 0 : bExtMode = sal_False;
606 0 : EndSelect();
607 0 : }
608 : /*
609 : * Ende einer Selektion; falls die Selektion leer ist,
610 : * ClearMark().
611 : */
612 :
613 :
614 :
615 0 : long SwWrtShell::SttLeaveSelect(const Point *, sal_Bool )
616 : {
617 0 : if(SwCrsrShell::HasSelection() && !IsSelTblCells() && bClearMark) {
618 0 : return 0;
619 : }
620 0 : ClearMark();
621 0 : return 1;
622 : }
623 : /*
624 : * Verlassen des Selektionsmodus in Additional Mode
625 : */
626 :
627 :
628 :
629 0 : long SwWrtShell::AddLeaveSelect(const Point *, sal_Bool )
630 : {
631 0 : if(IsTableMode()) LeaveAddMode();
632 0 : else if(SwCrsrShell::HasSelection())
633 0 : CreateCrsr();
634 0 : return 1;
635 : }
636 : /*
637 : * Additional Mode
638 : */
639 :
640 :
641 :
642 0 : void SwWrtShell::EnterAddMode()
643 : {
644 0 : if(IsTableMode()) return;
645 0 : if(bBlockMode)
646 0 : LeaveBlockMode();
647 0 : fnKillSel = &SwWrtShell::Ignore;
648 0 : fnSetCrsr = &SwWrtShell::SetCrsr;
649 0 : bAddMode = sal_True;
650 0 : bBlockMode = sal_False;
651 0 : bExtMode = sal_False;
652 0 : if(SwCrsrShell::HasSelection())
653 0 : CreateCrsr();
654 0 : Invalidate();
655 : }
656 :
657 :
658 :
659 0 : void SwWrtShell::LeaveAddMode()
660 : {
661 0 : fnKillSel = &SwWrtShell::ResetSelect;
662 0 : fnSetCrsr = &SwWrtShell::SetCrsrKillSel;
663 0 : bAddMode = sal_False;
664 0 : Invalidate();
665 0 : }
666 :
667 : /*
668 : * Block Mode
669 : */
670 :
671 0 : void SwWrtShell::EnterBlockMode()
672 : {
673 0 : bBlockMode = sal_False;
674 0 : EnterStdMode();
675 0 : bBlockMode = sal_True;
676 0 : CrsrToBlockCrsr();
677 0 : Invalidate();
678 0 : }
679 :
680 :
681 :
682 0 : void SwWrtShell::LeaveBlockMode()
683 : {
684 0 : bBlockMode = sal_False;
685 0 : BlockCrsrToCrsr();
686 0 : EndSelect();
687 0 : Invalidate();
688 0 : }
689 :
690 : // Einfuegemodus
691 :
692 :
693 :
694 0 : void SwWrtShell::SetInsMode( sal_Bool bOn )
695 : {
696 0 : bIns = bOn;
697 0 : SwCrsrShell::SetOverwriteCrsr( !bIns );
698 0 : const SfxBoolItem aTmp( SID_ATTR_INSERT, bIns );
699 0 : GetView().GetViewFrame()->GetBindings().SetState( aTmp );
700 0 : StartAction();
701 0 : EndAction();
702 0 : Invalidate();
703 0 : }
704 : //Overwrite mode is incompatible with red-lining
705 0 : void SwWrtShell::SetRedlineModeAndCheckInsMode( sal_uInt16 eMode )
706 : {
707 0 : SetRedlineMode( eMode );
708 0 : if (IsRedlineOn())
709 0 : SetInsMode( true );
710 0 : }
711 :
712 : /*
713 : * Rahmen bearbeiten
714 : */
715 :
716 :
717 0 : long SwWrtShell::BeginFrmDrag(const Point *pPt, sal_Bool)
718 : {
719 0 : fnDrag = &SwFEShell::Drag;
720 0 : if(bStartDrag)
721 : {
722 0 : Point aTmp( nStartDragX, nStartDragY );
723 0 : SwFEShell::BeginDrag( &aTmp, sal_False );
724 : }
725 : else
726 0 : SwFEShell::BeginDrag( pPt, sal_False );
727 0 : return 1;
728 : }
729 :
730 :
731 :
732 0 : void SwWrtShell::EnterSelFrmMode(const Point *pPos)
733 : {
734 0 : if(pPos)
735 : {
736 0 : nStartDragX = pPos->X();
737 0 : nStartDragY = pPos->Y();
738 0 : bStartDrag = sal_True;
739 : }
740 0 : bNoEdit = bLayoutMode = sal_True;
741 0 : HideCrsr();
742 :
743 : // gleicher Aufruf von BeginDrag an der SwFEShell
744 0 : fnDrag = &SwWrtShell::BeginFrmDrag;
745 0 : fnEndDrag = &SwWrtShell::UpdateLayoutFrm;
746 0 : SwBaseShell::SetFrmMode( FLY_DRAG_START, this );
747 0 : Invalidate();
748 0 : }
749 :
750 :
751 :
752 0 : void SwWrtShell::LeaveSelFrmMode()
753 : {
754 0 : fnDrag = &SwWrtShell::BeginDrag;
755 0 : fnEndDrag = &SwWrtShell::EndDrag;
756 0 : bLayoutMode = sal_False;
757 0 : bStartDrag = sal_False;
758 0 : Edit();
759 0 : SwBaseShell::SetFrmMode( FLY_DRAG_END, this );
760 0 : Invalidate();
761 0 : }
762 : /*------------------------------------------------------------------------
763 : Beschreibung: Rahmengebundenes Macro ausfuehren
764 : ------------------------------------------------------------------------*/
765 :
766 :
767 :
768 0 : IMPL_LINK( SwWrtShell, ExecFlyMac, void *, pFlyFmt )
769 : {
770 0 : const SwFrmFmt *pFmt = pFlyFmt ? (SwFrmFmt*)pFlyFmt : GetFlyFrmFmt();
771 : OSL_ENSURE(pFmt, "no frame format");
772 0 : const SvxMacroItem &rFmtMac = pFmt->GetMacro();
773 :
774 0 : if(rFmtMac.HasMacro(SW_EVENT_OBJECT_SELECT))
775 : {
776 0 : const SvxMacro &rMac = rFmtMac.GetMacro(SW_EVENT_OBJECT_SELECT);
777 0 : if( IsFrmSelected() )
778 0 : bLayoutMode = sal_True;
779 0 : CallChgLnk();
780 0 : ExecMacro( rMac );
781 : }
782 0 : return 0;
783 : }
784 :
785 :
786 :
787 0 : long SwWrtShell::UpdateLayoutFrm(const Point *pPt, sal_Bool )
788 : {
789 : // voerst Dummy
790 0 : SwFEShell::EndDrag( pPt, sal_False );
791 0 : fnDrag = &SwWrtShell::BeginFrmDrag;
792 0 : return 1;
793 : }
794 :
795 : /*
796 : * Handler fuer das Togglen der Modi. Liefern alten Mode zurueck.
797 : */
798 :
799 :
800 :
801 0 : long SwWrtShell::ToggleAddMode()
802 : {
803 0 : bAddMode ? LeaveAddMode(): EnterAddMode();
804 0 : Invalidate();
805 0 : return !bAddMode;
806 : }
807 :
808 :
809 0 : long SwWrtShell::ToggleBlockMode()
810 : {
811 0 : bBlockMode ? LeaveBlockMode(): EnterBlockMode();
812 0 : Invalidate();
813 0 : return !bBlockMode;
814 : }
815 :
816 :
817 0 : long SwWrtShell::ToggleExtMode()
818 : {
819 0 : bExtMode ? LeaveExtMode() : EnterExtMode();
820 0 : Invalidate();
821 0 : return !bExtMode;
822 : }
823 : /*
824 : * Draggen im Standard Modus (Selektieren von Inhalt)
825 : */
826 :
827 :
828 :
829 0 : long SwWrtShell::BeginDrag(const Point * /*pPt*/, sal_Bool )
830 : {
831 0 : if(bSelWrd)
832 : {
833 0 : bInSelect = sal_True;
834 0 : if( !IsCrsrPtAtEnd() )
835 0 : SwapPam();
836 :
837 0 : fnDrag = &SwWrtShell::ExtSelWrd;
838 0 : fnSetCrsr = &SwWrtShell::Ignore;
839 : }
840 0 : else if(bSelLn)
841 : {
842 0 : bInSelect = sal_True;
843 0 : fnDrag = &SwWrtShell::ExtSelLn;
844 0 : fnSetCrsr = &SwWrtShell::Ignore;
845 : }
846 : else
847 : {
848 0 : fnDrag = &SwWrtShell::Drag;
849 0 : SttSelect();
850 : }
851 :
852 0 : return 1;
853 : }
854 :
855 :
856 :
857 0 : long SwWrtShell::Drag(const Point *, sal_Bool )
858 : {
859 0 : if( IsSelTblCells() )
860 0 : aSelTblLink.Call(this);
861 :
862 0 : return 1;
863 : }
864 :
865 :
866 :
867 0 : long SwWrtShell::EndDrag(const Point * /*pPt*/, sal_Bool )
868 : {
869 0 : fnDrag = &SwWrtShell::BeginDrag;
870 0 : if( IsExtSel() )
871 0 : LeaveExtSel();
872 :
873 0 : if( IsSelTblCells() )
874 0 : aSelTblLink.Call(this);
875 0 : EndSelect();
876 0 : return 1;
877 : }
878 :
879 : // #i32329# Enhanced table selection
880 0 : sal_Bool SwWrtShell::SelectTableRowCol( const Point& rPt, const Point* pEnd, bool bRowDrag )
881 : {
882 0 : SwMvContext aMvContext(this);
883 0 : SttSelect();
884 0 : if(SelTblRowCol( rPt, pEnd, bRowDrag ))
885 : {
886 0 : fnSetCrsr = &SwWrtShell::SetCrsrKillSel;
887 0 : fnKillSel = &SwWrtShell::ResetSelect;
888 0 : return sal_True;
889 : }
890 0 : return sal_False;
891 : }
892 :
893 : /*------------------------------------------------------------------------
894 : Beschreibung: Selektion einer Tabellenzeile / Spalte
895 : ------------------------------------------------------------------------*/
896 :
897 0 : sal_Bool SwWrtShell::SelectTableRow()
898 : {
899 0 : if ( SelTblRow() )
900 : {
901 0 : fnSetCrsr = &SwWrtShell::SetCrsrKillSel;
902 0 : fnKillSel = &SwWrtShell::ResetSelect;
903 0 : return sal_True;
904 : }
905 0 : return sal_False;
906 : }
907 :
908 :
909 :
910 0 : sal_Bool SwWrtShell::SelectTableCol()
911 : {
912 0 : if ( SelTblCol() )
913 : {
914 0 : fnSetCrsr = &SwWrtShell::SetCrsrKillSel;
915 0 : fnKillSel = &SwWrtShell::ResetSelect;
916 0 : return sal_True;
917 : }
918 0 : return sal_False;
919 : }
920 :
921 0 : sal_Bool SwWrtShell::SelectTableCell()
922 : {
923 0 : if ( SelTblBox() )
924 : {
925 0 : fnSetCrsr = &SwWrtShell::SetCrsrKillSel;
926 0 : fnKillSel = &SwWrtShell::ResetSelect;
927 0 : return sal_True;
928 : }
929 0 : return sal_False;
930 : }
931 : /*------------------------------------------------------------------------
932 : Beschreibung: Prueft, ob eine Wortselektion vorliegt.
933 : Gemaess den Regeln fuer intelligentes Cut / Paste
934 : werden umgebende Spaces rausgeschnitten.
935 : Return: Liefert Art der Wortselektion zurueck.
936 : ------------------------------------------------------------------------*/
937 :
938 :
939 :
940 0 : int SwWrtShell::IntelligentCut(int nSelection, sal_Bool bCut)
941 : {
942 : // kein intelligentes Drag and Drop bei Mehrfachselektion
943 : // es existieren mehrere Cursor, da ein zweiter bereits
944 : // an die Zielposition gesetzt wurde
945 0 : if( IsAddMode() || !(nSelection & nsSelectionType::SEL_TXT) )
946 0 : return sal_False;
947 :
948 0 : String sTxt;
949 0 : CharClass& rCC = GetAppCharClass();
950 :
951 : // wenn das erste und das letzte Zeichen kein Wortzeichen ist,
952 : // ist kein Wort selektiert.
953 0 : sal_Unicode cPrev = GetChar(sal_False);
954 0 : sal_Unicode cNext = GetChar(sal_True, -1);
955 0 : if( !cPrev || !cNext ||
956 0 : !rCC.isLetterNumeric( ( sTxt = cPrev), 0 ) ||
957 0 : !rCC.isLetterNumeric( ( sTxt = cNext), 0 ) )
958 0 : return NO_WORD;
959 :
960 0 : cPrev = GetChar(sal_False, -1);
961 0 : cNext = GetChar(sal_True);
962 :
963 0 : int cWord = NO_WORD;
964 : // ist ein Wort selektiert?
965 0 : if(!cWord && cPrev && cNext &&
966 : CH_TXTATR_BREAKWORD != cPrev && CH_TXTATR_INWORD != cPrev &&
967 : CH_TXTATR_BREAKWORD != cNext && CH_TXTATR_INWORD != cNext &&
968 0 : !rCC.isLetterNumeric( ( sTxt = cPrev), 0 ) &&
969 0 : !rCC.isLetterNumeric( ( sTxt = cNext), 0 ) )
970 0 : cWord = WORD_NO_SPACE;
971 :
972 0 : if(cWord == WORD_NO_SPACE && ' ' == cPrev )
973 : {
974 0 : cWord = WORD_SPACE_BEFORE;
975 : // Space davor loeschen
976 0 : if(bCut)
977 : {
978 0 : Push();
979 0 : if(IsCrsrPtAtEnd())
980 0 : SwapPam();
981 0 : ClearMark();
982 0 : SetMark();
983 0 : SwCrsrShell::Left(1,CRSR_SKIP_CHARS);
984 0 : SwFEShell::Delete();
985 0 : Pop( sal_False );
986 : }
987 : }
988 0 : else if(cWord == WORD_NO_SPACE && cNext == ' ')
989 : {
990 0 : cWord = WORD_SPACE_AFTER;
991 : // Space dahinter loeschen
992 0 : if(bCut) {
993 0 : Push();
994 0 : if(!IsCrsrPtAtEnd()) SwapPam();
995 0 : ClearMark();
996 0 : SetMark();
997 0 : SwCrsrShell::Right(1,CRSR_SKIP_CHARS);
998 0 : SwFEShell::Delete();
999 0 : Pop( sal_False );
1000 : }
1001 : }
1002 0 : return cWord;
1003 : }
1004 :
1005 :
1006 :
1007 : // jump to the next / previous hyperlink - inside text and also
1008 : // on graphics
1009 0 : sal_Bool SwWrtShell::SelectNextPrevHyperlink( sal_Bool bNext )
1010 : {
1011 0 : StartAction();
1012 0 : sal_Bool bRet = SwCrsrShell::SelectNxtPrvHyperlink( bNext );
1013 0 : if( !bRet )
1014 : {
1015 : // will we have this feature?
1016 0 : EnterStdMode();
1017 0 : if( bNext )
1018 0 : SttEndDoc(sal_True);
1019 : else
1020 0 : SttEndDoc(sal_False);
1021 0 : bRet = SwCrsrShell::SelectNxtPrvHyperlink( bNext );
1022 : }
1023 0 : EndAction();
1024 :
1025 0 : sal_Bool bCreateXSelection = sal_False;
1026 0 : const sal_Bool bFrmSelected = IsFrmSelected() || IsObjSelected();
1027 0 : if( IsSelection() )
1028 : {
1029 0 : if ( bFrmSelected )
1030 0 : UnSelectFrm();
1031 :
1032 : // Funktionspointer fuer das Aufheben der Selektion setzen
1033 : // bei Cursor setzen
1034 0 : fnKillSel = &SwWrtShell::ResetSelect;
1035 0 : fnSetCrsr = &SwWrtShell::SetCrsrKillSel;
1036 0 : bCreateXSelection = sal_True;
1037 : }
1038 0 : else if( bFrmSelected )
1039 : {
1040 0 : EnterSelFrmMode();
1041 0 : bCreateXSelection = sal_True;
1042 : }
1043 0 : else if( (CNT_GRF | CNT_OLE ) & GetCntType() )
1044 : {
1045 0 : SelectObj( GetCharRect().Pos() );
1046 0 : EnterSelFrmMode();
1047 0 : bCreateXSelection = sal_True;
1048 : }
1049 :
1050 0 : if( bCreateXSelection )
1051 0 : SwTransferable::CreateSelection( *this );
1052 :
1053 0 : return bRet;
1054 30 : }
1055 :
1056 :
1057 : /* fuer den Erhalt der Selektion wird nach SetMark() der Cursor
1058 : * nach links bewegt, damit er durch das Einfuegen von Text nicht
1059 : * verschoben wird. Da auf der CORE-Seite am aktuellen Cursor
1060 : * eine bestehende Selektion aufgehoben wird, wird der Cursor auf
1061 : * den Stack gepushed. Nach dem Verschieben werden sie wieder
1062 : * zusammengefasst. */
1063 :
1064 :
1065 :
1066 :
1067 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|