1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <hintids.hxx>
22 #include <sfx2/bindings.hxx>
23 #include <sfx2/viewfrm.hxx>
24 #include <svl/eitem.hxx>
25 #include <svl/macitem.hxx>
26 #include <unotools/charclass.hxx>
27 #include <sfx2/event.hxx>
28 #include <osl/diagnose.h>
37 #include <swdtflvr.hxx>
39 #include <wordcountdialog.hxx>
41 #include <vcl/uitest/logger.hxx>
42 #include <vcl/uitest/eventdescription.hxx>
44 #include <officecfg/Office/Common.hxx>
45 #include <strings.hrc>
47 #include <svx/svdview.hxx>
49 namespace com::sun::star::util
{
50 struct SearchOptions2
;
53 using namespace ::com::sun::star::util
;
55 static tools::Long nStartDragX
= 0, nStartDragY
= 0;
56 static bool bStartDrag
= false;
58 void SwWrtShell::Invalidate()
60 // to avoid making the slot volatile, invalidate it every time if something could have been changed
61 // this is still much cheaper than asking for the state every 200 ms (and avoid background processing)
62 GetView().GetViewFrame().GetBindings().Invalidate( FN_STAT_SELMODE
);
63 GetView().GetViewFrame().GetBindings().Update(FN_STAT_SELMODE
); // make selection mode control icon update immediately
64 SwWordCountWrapper
*pWrdCnt
= static_cast<SwWordCountWrapper
*>(GetView().GetViewFrame().GetChildWindow(SwWordCountWrapper::GetChildWindowId()));
66 pWrdCnt
->UpdateCounts();
69 bool SwWrtShell::SelNearestWrd()
71 SwMvContext
aMvContext(this);
72 if( !IsInWord() && !IsEndWrd() && !IsStartWord() )
75 Left(SwCursorSkipMode::Cells
, false, 1, false );
79 bool SwWrtShell::SelWrd(const Point
*pPt
, sal_Int16 nWordType
)
83 SwMvContext
aMvContext(this);
85 bRet
= SwCursorShell::SelectWordWT( pPt
, nWordType
);
97 void SwWrtShell::SelSentence(const Point
*pPt
)
100 SwMvContext
aMvContext(this);
102 SwCursorShell::GoStartSentence();
104 SwCursorShell::GoEndSentence();
110 m_bSelWrd
= false; // disable SelWord, otherwise no SelLine goes on
113 void SwWrtShell::SelPara(const Point
*pPt
)
116 SwMvContext
aMvContext(this);
118 SwCursorShell::MovePara( GoCurrPara
, fnParaStart
);
120 SwCursorShell::MovePara( GoCurrPara
, fnParaEnd
);
126 m_bSelWrd
= false; // disable SelWord, otherwise no SelLine goes on
129 void SwWrtShell::SelAll()
131 const bool bLockedView
= IsViewLocked();
136 SwMvContext
aMvContext(this);
137 bool bMoveTable
= false;
138 std::optional
<SwPosition
> oStartPos
;
139 std::optional
<SwPosition
> oEndPos
;
140 SwShellCursor
* pTmpCursor
= nullptr;
142 // Query these early, before we move the cursor.
143 bool bHasWholeTabSelection
= HasWholeTabSelection();
144 bool bIsCursorInTable
= IsCursorInTable();
146 if (!bHasWholeTabSelection
147 && ( !bIsCursorInTable
148 || getShellCursor(false)->GetMarkNode().FindTableNode() == nullptr
149 || !ExtendedSelectedAll())) // ESA inside table -> else branch
151 if ( IsSelection() && IsCursorPtAtEnd() )
153 pTmpCursor
= getShellCursor( false );
156 oStartPos
.emplace( *pTmpCursor
->GetPoint() );
157 oEndPos
.emplace( *pTmpCursor
->GetMark() );
160 bool bIsFullSel
= !MoveSection( GoCurrSection
, fnSectionStart
);
162 bIsFullSel
&= !MoveSection( GoCurrSection
, fnSectionEnd
);
163 Pop(SwCursorShell::PopMode::DeleteCurrent
);
164 GoStart(true, &bMoveTable
, false, !bIsFullSel
);
166 GoEnd(true, &bMoveTable
);
170 if (MoveOutOfTable())
171 { // select outer text
172 EnterStdMode(); // delete m_pTableCursor
173 // GoStart(true, &bMoveTable, false, true);
174 MoveSection(GoCurrSection
, fnSectionStart
); // don't move into prev table
176 MoveSection(GoCurrSection
, fnSectionEnd
); // don't move to different cell
180 TrySelectOuterTable();
184 bool bNeedsExtendedSelectAll
= StartsWith_() != StartsWith::None
;
186 // the GoEnd() could have created a table selection, if so avoid ESA.
187 if (bNeedsExtendedSelectAll
&& bIsCursorInTable
)
189 bNeedsExtendedSelectAll
= !HasWholeTabSelection();
192 if (bNeedsExtendedSelectAll
)
194 ExtendedSelectAll(/*bFootnotes =*/ false);
197 SwDoc
*pDoc
= GetDoc();
200 pDoc
->SetPrepareSelAll();
205 pTmpCursor
= getShellCursor( false );
208 // Some special handling for sections (e.g. TOC) at the beginning of the document body
209 // to avoid the selection of the first section
210 // if the last selection was behind the first section or
211 // if the last selection was already the first section
212 // In this both cases we select to the end of document
213 if( ( *pTmpCursor
->GetPoint() < *oEndPos
||
214 ( *oStartPos
== *pTmpCursor
->GetMark() &&
215 *oEndPos
== *pTmpCursor
->GetPoint() ) ) && !bNeedsExtendedSelectAll
)
216 SwCursorShell::SttEndDoc(false);
221 LockView( bLockedView
);
224 // Description: Text search
226 sal_Int32
SwWrtShell::SearchPattern( const i18nutil::SearchOptions2
& rSearchOpt
, bool bSearchInNotes
,
227 SwDocPositions eStt
, SwDocPositions eEnd
,
228 FindRanges eFlags
, bool bReplace
)
230 // no enhancement of existing selections
231 if(!(eFlags
& FindRanges::InSel
))
233 bool bCancel
= false;
234 sal_Int32 nRet
= Find_Text(rSearchOpt
, bSearchInNotes
, eStt
, eEnd
, bCancel
, eFlags
, bReplace
);
238 nRet
= SAL_MAX_INT32
;
243 // Description: search for templates
245 sal_Int32
SwWrtShell::SearchTempl( const OUString
&rTempl
,
246 SwDocPositions eStt
, SwDocPositions eEnd
,
247 FindRanges eFlags
, const OUString
* pReplTempl
)
249 // no enhancement of existing selections
250 if(!(eFlags
& FindRanges::InSel
))
252 SwTextFormatColl
*pColl
= GetParaStyle(rTempl
, SwWrtShell::GETSTYLE_CREATESOME
);
253 SwTextFormatColl
*pReplaceColl
= nullptr;
255 pReplaceColl
= GetParaStyle(*pReplTempl
, SwWrtShell::GETSTYLE_CREATESOME
);
257 bool bCancel
= false;
258 sal_Int32 nRet
= FindFormat(pColl
? *pColl
: GetDfltTextFormatColl(),
259 eStt
,eEnd
, bCancel
, eFlags
, pReplaceColl
);
263 nRet
= SAL_MAX_INT32
;
268 // search for attributes
270 sal_Int32
SwWrtShell::SearchAttr( const SfxItemSet
& rFindSet
, bool bNoColls
,
271 SwDocPositions eStart
, SwDocPositions eEnd
,
272 FindRanges eFlags
, const i18nutil::SearchOptions2
* pSearchOpt
,
273 const SfxItemSet
* pReplaceSet
)
275 // no enhancement of existing selections
276 if (!(eFlags
& FindRanges::InSel
))
280 bool bCancel
= false;
281 sal_Int32 nRet
= FindAttrs(rFindSet
, bNoColls
, eStart
, eEnd
, bCancel
, eFlags
, pSearchOpt
, pReplaceSet
);
286 nRet
= SAL_MAX_INT32
;
293 void SwWrtShell::PushMode()
295 m_pModeStack
= new ModeStack( m_pModeStack
, m_bIns
, m_bExtMode
, m_bAddMode
, m_bBlockMode
);
298 void SwWrtShell::PopMode()
300 if ( nullptr == m_pModeStack
)
303 if ( m_bExtMode
&& !m_pModeStack
->bExt
)
305 if ( m_bAddMode
&& !m_pModeStack
->bAdd
)
307 if ( m_bBlockMode
&& !m_pModeStack
->bBlock
)
309 m_bIns
= m_pModeStack
->bIns
;
311 m_pModeStack
= std::move(m_pModeStack
->pNext
);
314 // Two methods for setting cursors: the first maps at the
315 // eponymous methods in the CursorShell, the second removes
316 // all selections at first.
318 tools::Long
SwWrtShell::SetCursor(const Point
*pPt
, bool bTextOnly
, ScrollSizeMode eScrollSizeMode
)
320 // Remove a possibly present selection at the position
323 if(!IsInSelect() && TestCurrPam(*pPt
)) {
327 return SwCursorShell::SetCursor(*pPt
, bTextOnly
, true, false, eScrollSizeMode
);
330 tools::Long
SwWrtShell::SetCursorKillSel(const Point
*pPt
, bool bTextOnly
, ScrollSizeMode eScrollSizeMode
)
332 SwActContext
aActContext(this);
333 ResetSelect(pPt
, false, ScrollSizeMode::ScrollSizeDefault
);
334 return SwCursorShell::SetCursor(*pPt
, bTextOnly
, true, false, eScrollSizeMode
);
337 void SwWrtShell::UnSelectFrame()
339 // Remove Frame selection with guaranteed invalid position
340 Point
aPt(LONG_MIN
, LONG_MIN
);
342 SwTransferable::ClearSelection( *this );
345 // Remove of all selections
347 tools::Long
SwWrtShell::ResetSelect(const Point
*, bool, ScrollSizeMode
)
356 // SwActContext opens an Action -
357 // to avoid problems in the basic process with the
358 // shell switching, GetChgLnk().Call() may be called
359 // after EndAction().
361 SwActContext
aActContext(this);
362 m_bSelWrd
= m_bSelLn
= false;
365 m_fnKillSel
= &SwWrtShell::Ignore
;
366 m_fnSetCursor
= &SwWrtShell::SetCursor
;
369 // After canceling of all selections an update of Attr-Controls
370 // could be necessary.
371 GetChgLnk().Call(nullptr);
373 if ( GetEnhancedTableSelection() != SwTable::SEARCH_NONE
)
374 UnsetEnhancedTableSelection();
377 SwTransferable::ClearSelection( *this );
381 bool SwWrtShell::IsSplitVerticalByDefault() const
383 return GetDoc()->IsSplitVerticalByDefault();
386 void SwWrtShell::SetSplitVerticalByDefault(bool value
)
388 GetDoc()->SetSplitVerticalByDefault(value
);
393 tools::Long
SwWrtShell::Ignore(const Point
*, bool, ScrollSizeMode
)
398 // Begin of a selection process.
400 void SwWrtShell::SttSelect()
408 SwShellCursor
* pTmp
= getShellCursor( true );
409 if( !pTmp
->HasMark() )
412 m_fnKillSel
= &SwWrtShell::Ignore
;
413 m_fnSetCursor
= &SwWrtShell::SetCursor
;
416 SwTransferable::CreateSelection( *this );
421 void collectUIInformation(SwShellCursor
* pCursor
)
423 EventDescription aDescription
;
424 OUString aSelStart
= OUString::number(pCursor
->Start()->GetContentIndex());
425 OUString aSelEnd
= OUString::number(pCursor
->End()->GetContentIndex());
427 aDescription
.aParameters
= {{"START_POS", aSelStart
}, {"END_POS", aSelEnd
}};
428 aDescription
.aAction
= "SELECT";
429 aDescription
.aID
= "writer_edit";
430 aDescription
.aKeyWord
= "SwEditWinUIObject";
431 aDescription
.aParent
= "MainWindow";
433 UITestLogger::getInstance().logEvent(aDescription
);
438 // End of a selection process.
440 void SwWrtShell::EndSelect()
442 if(m_bInSelect
&& !m_bExtMode
)
452 m_fnSetCursor
= &SwWrtShell::SetCursorKillSel
;
453 m_fnKillSel
= &SwWrtShell::ResetSelect
;
456 SwWordCountWrapper
*pWrdCnt
= static_cast<SwWordCountWrapper
*>(GetView().GetViewFrame().GetChildWindow(SwWordCountWrapper::GetChildWindowId()));
458 pWrdCnt
->UpdateCounts();
460 collectUIInformation(GetCursor_());
463 void SwWrtShell::ExtSelWrd(const Point
*pPt
, bool )
465 SwMvContext
aMvContext(this);
469 // Bug 66823: actual crsr has in additional mode no selection?
470 // Then destroy the actual and go to prev, this will be expand
471 if( !HasMark() && GoPrevCursor() )
473 bool bHasMark
= HasMark(); // that's wrong!
482 // check the direction of the selection with the new point
483 bool bMoveCursor
= true, bToTop
= false;
484 SwCursorShell::SelectWord( &m_aStart
); // select the startword
485 SwCursorShell::Push(); // save the cursor
486 SwCursorShell::SetCursor( *pPt
); // and check the direction
488 switch( SwCursorShell::CompareCursorStackMkCurrPt())
490 case -1: bToTop
= false; break;
491 case 1: bToTop
= true; break;
492 default: bMoveCursor
= false; break;
495 SwCursorShell::Pop(SwCursorShell::PopMode::DeleteCurrent
); // restore the saved cursor
500 // select to Top but cursor select to Bottom? or
501 // select to Bottom but cursor select to Top? --> swap the cursor
505 SwCursorShell::Push(); // save cur cursor
506 if( SwCursorShell::SelectWord( pPt
)) // select the current word
514 SwCursorShell::Pop(SwCursorShell::PopMode::DeleteCurrent
);
520 void SwWrtShell::ExtSelLn(const Point
*pPt
, bool )
522 SwMvContext
aMvContext(this);
523 SwCursorShell::SetCursor(*pPt
);
527 // Bug 66823: actual crsr has in additional mode no selection?
528 // Then destroy the actual and go to prev, this will be expand
529 if( !HasMark() && GoPrevCursor() )
531 bool bHasMark
= HasMark(); // that's wrong!
540 // if applicable fit the selection to the "Mark"
541 bool bToTop
= !IsCursorPtAtEnd();
544 // The "Mark" has to be at the end or the beginning of the line.
545 if( bToTop
? !IsEndSentence() : !IsStartSentence() )
550 SwCursorShell::Right(1,SwCursorSkipMode::Chars
);
551 SwCursorShell::GoEndSentence();
554 SwCursorShell::GoStartSentence();
559 SwCursorShell::GoStartSentence();
561 SwCursorShell::GoEndSentence();
564 // Back into the standard mode: no mode, no selections.
566 void SwWrtShell::EnterStdMode()
572 m_bBlockMode
= false;
582 // SwActContext opens and action which has to be
583 // closed prior to the call of
584 // GetChgLnk().Call()
585 SwActContext
aActContext(this);
586 m_bSelWrd
= m_bSelLn
= false;
587 if( !IsRetainSelection() )
590 m_fnSetCursor
= &SwWrtShell::SetCursorKillSel
;
591 m_fnKillSel
= &SwWrtShell::ResetSelect
;
594 SwTransferable::ClearSelection( *this );
597 void SwWrtShell::AssureStdMode()
599 // deselect any drawing or frame and leave editing mode
600 if (SdrView
* pSdrView
= GetDrawView())
602 if (pSdrView
->IsTextEdit())
604 bool bLockView
= IsViewLocked();
609 // go out of the frame
610 Point
aPt(LONG_MIN
, LONG_MIN
);
611 SelectObj(aPt
, SW_LEAVE_FRAME
);
613 if (IsSelFrameMode() || GetSelectedObjCount())
617 GetView().LeaveDrawCreate();
620 GetView().StopShellTimer();
628 void SwWrtShell::EnterExtMode()
638 m_bBlockMode
= false;
642 void SwWrtShell::LeaveExtMode()
648 // End of a selection; if the selection is empty,
651 void SwWrtShell::SttLeaveSelect()
653 if(SwCursorShell::HasSelection() && !IsSelTableCells() && m_bClearMark
) {
659 // Leaving of the selection mode in additional mode
661 void SwWrtShell::AddLeaveSelect()
663 if(IsTableMode()) LeaveAddMode();
664 else if(SwCursorShell::HasSelection())
670 void SwWrtShell::EnterAddMode()
672 if(IsTableMode()) return;
675 m_fnSetCursor
= &SwWrtShell::SetCursor
;
677 m_bBlockMode
= false;
679 if(SwCursorShell::HasSelection())
684 void SwWrtShell::LeaveAddMode()
686 m_fnKillSel
= &SwWrtShell::ResetSelect
;
687 m_fnSetCursor
= &SwWrtShell::SetCursorKillSel
;
694 void SwWrtShell::EnterBlockMode()
696 m_bBlockMode
= false;
699 CursorToBlockCursor();
703 void SwWrtShell::LeaveBlockMode()
705 m_bBlockMode
= false;
706 BlockCursorToCursor();
713 void SwWrtShell::ImplSetInsMode(bool bOn
)
716 SwCursorShell::SetOverwriteCursor( !m_bIns
);
717 const SfxBoolItem
aTmp( SID_ATTR_INSERT
, m_bIns
);
718 GetView().GetViewFrame().GetBindings().SetState( aTmp
);
724 void SwWrtShell::SetInsMode( bool bOn
)
726 const bool bDoAsk
= officecfg::Office::Common::Misc::QuerySetInsMode::get();
729 VclAbstractDialogFactory
* pFact
= VclAbstractDialogFactory::Create();
730 auto pDlg
= pFact
->CreateQueryDialog(
731 GetView().GetFrameWeld(), SwResId(STR_QUERY_INSMODE_TITLE
),
732 SwResId(STR_QUERY_INSMODE_TEXT
), SwResId(STR_QUERY_INSMODE_QUESTION
), true);
733 pDlg
->StartExecuteAsync( [this, pDlg
] (sal_Int32 nResult
)->void
735 if (pDlg
->ShowAgain() == false)
737 std::shared_ptr
<comphelper::ConfigurationChanges
> xChanges(
738 comphelper::ConfigurationChanges::create());
739 officecfg::Office::Common::Misc::QuerySetInsMode::set(false, xChanges
);
742 if (nResult
== RET_YES
)
743 ImplSetInsMode(false);
751 //Overwrite mode is incompatible with red-lining
752 void SwWrtShell::SetRedlineFlagsAndCheckInsMode( RedlineFlags eMode
)
754 SetRedlineFlags( eMode
);
761 void SwWrtShell::BeginFrameDrag(const Point
*pPt
, bool bIsShift
)
763 m_fnDrag
= &SwFEShell::Drag
;
766 Point
aTmp( nStartDragX
, nStartDragY
);
767 SwFEShell::BeginDrag( &aTmp
, bIsShift
);
770 SwFEShell::BeginDrag( pPt
, bIsShift
);
773 void SwWrtShell::EnterSelFrameMode(const Point
*pPos
)
777 nStartDragX
= pPos
->X();
778 nStartDragY
= pPos
->Y();
781 m_bLayoutMode
= true;
784 // equal call of BeginDrag in the SwFEShell
785 m_fnDrag
= &SwWrtShell::BeginFrameDrag
;
786 m_fnEndDrag
= &SwWrtShell::UpdateLayoutFrame
;
787 SwBaseShell::SetFrameMode( FLY_DRAG_START
, this );
791 void SwWrtShell::LeaveSelFrameMode()
793 m_fnDrag
= &SwWrtShell::BeginDrag
;
794 m_fnEndDrag
= &SwWrtShell::DefaultEndDrag
;
795 m_bLayoutMode
= false;
798 SwBaseShell::SetFrameMode( FLY_DRAG_END
, this );
802 // Description: execute framebound macro
804 IMPL_LINK( SwWrtShell
, ExecFlyMac
, const SwFlyFrameFormat
*, pFlyFormat
, void )
806 const SwFrameFormat
*pFormat
= pFlyFormat
? static_cast<const SwFrameFormat
*>(pFlyFormat
) : GetFlyFrameFormat();
807 assert(pFormat
&& "no frame format");
808 const SvxMacroItem
&rFormatMac
= pFormat
->GetMacro();
810 if(rFormatMac
.HasMacro(SvMacroItemId::SwObjectSelect
))
812 const SvxMacro
&rMac
= rFormatMac
.GetMacro(SvMacroItemId::SwObjectSelect
);
813 if( IsFrameSelected() )
814 m_bLayoutMode
= true;
820 void SwWrtShell::UpdateLayoutFrame(const Point
*, bool )
823 SwFEShell::EndDrag();
824 m_fnDrag
= &SwWrtShell::BeginFrameDrag
;
827 // Handler for toggling the modes. Returns back the old mode.
829 void SwWrtShell::ToggleAddMode()
831 m_bAddMode
? LeaveAddMode(): EnterAddMode();
835 void SwWrtShell::ToggleBlockMode()
837 m_bBlockMode
? LeaveBlockMode(): EnterBlockMode();
841 void SwWrtShell::ToggleExtMode()
843 m_bExtMode
? LeaveExtMode() : EnterExtMode();
847 // Dragging in standard mode (Selecting of content)
849 void SwWrtShell::BeginDrag(const Point
* /*pPt*/, bool )
854 if( !IsCursorPtAtEnd() )
857 m_fnDrag
= &SwWrtShell::ExtSelWrd
;
858 m_fnSetCursor
= &SwWrtShell::Ignore
;
863 m_fnDrag
= &SwWrtShell::ExtSelLn
;
864 m_fnSetCursor
= &SwWrtShell::Ignore
;
868 m_fnDrag
= &SwWrtShell::DefaultDrag
;
873 void SwWrtShell::DefaultDrag(const Point
*, bool )
875 if( IsSelTableCells() )
876 m_aSelTableLink
.Call(*this);
879 void SwWrtShell::DefaultEndDrag(const Point
* /*pPt*/, bool )
881 m_fnDrag
= &SwWrtShell::BeginDrag
;
885 if( IsSelTableCells() )
886 m_aSelTableLink
.Call(*this);
890 // #i32329# Enhanced table selection
891 bool SwWrtShell::SelectTableRowCol( const Point
& rPt
, const Point
* pEnd
, bool bRowDrag
)
893 SwMvContext
aMvContext(this);
895 if(SelTableRowCol( rPt
, pEnd
, bRowDrag
))
897 m_fnSetCursor
= &SwWrtShell::SetCursorKillSel
;
898 m_fnKillSel
= &SwWrtShell::ResetSelect
;
904 // Description: Selection of a table line or column
906 void SwWrtShell::SelectTableRow()
910 m_fnSetCursor
= &SwWrtShell::SetCursorKillSel
;
911 m_fnKillSel
= &SwWrtShell::ResetSelect
;
915 void SwWrtShell::SelectTableCol()
919 m_fnSetCursor
= &SwWrtShell::SetCursorKillSel
;
920 m_fnKillSel
= &SwWrtShell::ResetSelect
;
924 void SwWrtShell::SelectTableCell()
928 m_fnSetCursor
= &SwWrtShell::SetCursorKillSel
;
929 m_fnKillSel
= &SwWrtShell::ResetSelect
;
933 // Description: Check if a word selection is present.
934 // According to the rules for intelligent cut / paste
935 // surrounding spaces are cut out.
936 // Return: Delivers the type of the word selection.
938 int SwWrtShell::IntelligentCut(SelectionType nSelection
, bool bCut
)
940 // On multiple selection no intelligent drag and drop
941 // there are multiple cursors, since a second was placed
942 // already at the target position.
943 if( IsAddMode() || !(nSelection
& SelectionType::Text
) )
947 CharClass
& rCC
= GetAppCharClass();
949 // If the first character is no word character,
951 sal_Unicode cPrev
= GetChar(false);
952 sal_Unicode cNext
= GetChar(true, -1);
953 if( !cPrev
|| !cNext
||
954 !rCC
.isLetterNumeric( ( sText
= OUString(cPrev
) ), 0 ) ||
955 !rCC
.isLetterNumeric( ( sText
= OUString(cNext
) ), 0 ) )
958 cPrev
= GetChar(false, -1);
962 // is a word selected?
963 if (cPrev
&& cNext
&&
964 CH_TXTATR_BREAKWORD
!= cPrev
&& CH_TXTATR_INWORD
!= cPrev
&&
965 CH_TXTATR_BREAKWORD
!= cNext
&& CH_TXTATR_INWORD
!= cNext
&&
966 !rCC
.isLetterNumeric( ( sText
= OUString(cPrev
) ), 0 ) &&
967 !rCC
.isLetterNumeric( ( sText
= OUString(cNext
) ), 0 ) )
968 cWord
= WORD_NO_SPACE
;
970 if(cWord
== WORD_NO_SPACE
&& ' ' == cPrev
)
972 cWord
= WORD_SPACE_BEFORE
;
973 // delete the space before
977 if(IsCursorPtAtEnd())
981 SwCursorShell::Left(1,SwCursorSkipMode::Chars
);
982 SwFEShell::Delete(true);
983 Pop(SwCursorShell::PopMode::DeleteCurrent
);
986 else if(cWord
== WORD_NO_SPACE
&& cNext
== ' ')
988 cWord
= WORD_SPACE_AFTER
;
989 // delete the space behind
992 if(!IsCursorPtAtEnd()) SwapPam();
995 SwCursorShell::Right(1,SwCursorSkipMode::Chars
);
996 SwFEShell::Delete(true);
997 Pop(SwCursorShell::PopMode::DeleteCurrent
);
1003 // jump to the next / previous hyperlink - inside text and also
1005 void SwWrtShell::SelectNextPrevHyperlink( bool bNext
)
1008 bool bRet
= SwCursorShell::SelectNxtPrvHyperlink( bNext
);
1009 if( !bRet
) // didn't find? wrap and check again
1011 SwShellCursor
* pCursor
= GetCursor_();
1012 SwCursorSaveState
aSaveState(*pCursor
);
1018 bRet
= SwCursorShell::SelectNxtPrvHyperlink(bNext
);
1019 if (!bRet
) // didn't find again? restore cursor position and bail
1021 pCursor
->RestoreSavePos();
1022 EndAction(true); // don't scroll to restored cursor position
1028 bool bCreateXSelection
= false;
1029 const bool bFrameSelected
= IsFrameSelected() || GetSelectedObjCount();
1032 if ( bFrameSelected
)
1035 // Set the function pointer for the canceling of the selection
1037 m_fnKillSel
= &SwWrtShell::ResetSelect
;
1038 m_fnSetCursor
= &SwWrtShell::SetCursorKillSel
;
1039 bCreateXSelection
= true;
1041 else if( bFrameSelected
)
1043 EnterSelFrameMode();
1044 bCreateXSelection
= true;
1046 else if( (CNT_GRF
| CNT_OLE
) & GetCntType() )
1048 SelectObj( GetCharRect().Pos() );
1049 EnterSelFrameMode();
1050 bCreateXSelection
= true;
1053 if( bCreateXSelection
)
1054 SwTransferable::CreateSelection( *this );
1057 // For the preservation of the selection the cursor will be moved left
1058 // after SetMark(), so that the cursor is not moved by inserting text.
1059 // Because a present selection at the CORE page is cleared at the
1060 // current cursor position, the cursor will be pushed on the stack.
1061 // After moving, they will again resummarized.
1063 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */