Coverage Report

Created: 2026-03-31 11:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sw/source/uibase/wrtsh/wrtsh4.cxx
Line
Count
Source
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 <wrtsh.hxx>
21
#include <viscrs.hxx>
22
23
#include <LibreOfficeKit/LibreOfficeKitEnums.h>
24
#include <comphelper/string.hxx>
25
#include <sfx2/lokhelper.hxx>
26
27
// Private methods, which move the cursor over search.
28
// The removal of the selection must be made on the level above.
29
30
// The beginning of a word is the follow of a
31
// non-delimiter to delimiter. Furthermore, the follow of
32
// non-sentence separators on sentence separator.
33
// The begin of paragraph is also the word beginning.
34
35
void SwWrtShell::SttWrd()
36
0
{
37
0
    if ( IsSttPara() )
38
0
        return;
39
        // Create temporary cursor without selection.
40
0
    Push();
41
0
    ClearMark();
42
0
    if( !GoStartWord() )
43
            // not found --> go to the beginning of the paragraph.
44
0
        SwCursorShell::MovePara( GoCurrPara, fnParaStart );
45
0
    ClearMark();
46
        // If Mark was previously set, summarize.
47
0
    Combine();
48
0
}
49
50
// The end of a word is the follow of separator to nonseparator.
51
// The end of a word is also the sequence of word separators to
52
// punctuation marks.
53
// The end of a paragraph is also the end of a word.
54
55
void SwWrtShell::EndWrd()
56
0
{
57
0
    if ( IsEndWrd() )
58
0
        return;
59
        // Create temporary cursor without selection.
60
0
    Push();
61
0
    ClearMark();
62
0
    if( !GoEndWord() )
63
            // not found --> go to the end of the paragraph.
64
0
        SwCursorShell::MovePara(GoCurrPara, fnParaEnd);
65
0
    ClearMark();
66
        // If Mark was previously set, summarize.
67
0
    Combine();
68
0
}
69
70
bool SwWrtShell::NxtWrd_()
71
0
{
72
0
    bool bRet = false;
73
0
    while( IsEndPara() )               // If already at the end, then the next???
74
0
    {
75
0
        if(!SwCursorShell::Right(1,SwCursorSkipMode::Chars))  // Document - end ??
76
0
        {
77
0
            Pop(SwCursorShell::PopMode::DeleteCurrent);
78
0
            return bRet;
79
0
        }
80
0
        bRet = IsStartWord();
81
0
    }
82
0
    Push();
83
0
    ClearMark();
84
0
    while( !bRet )
85
0
    {
86
0
        if( !GoNextWord() )
87
0
        {
88
0
            if( (!IsEndPara() && !SwCursorShell::MovePara( GoCurrPara, fnParaEnd ) )
89
0
                || !SwCursorShell::Right(1,SwCursorSkipMode::Chars) )
90
0
                break;
91
0
            bRet = IsStartWord();
92
0
        }
93
0
        else
94
0
            bRet = true;
95
0
    }
96
0
    ClearMark();
97
0
    Combine();
98
0
    return bRet;
99
0
}
100
101
bool SwWrtShell::PrvWrd_()
102
0
{
103
0
    bool bRet = false;
104
0
    while( IsSttPara() )
105
0
    {                            // if already at the beginning, then the next???
106
0
        if(!SwCursorShell::Left(1,SwCursorSkipMode::Chars))
107
0
        {                        // Document - beginning ??
108
0
            Pop(SwCursorShell::PopMode::DeleteCurrent);
109
0
            return bRet;
110
0
        }
111
0
        bRet = IsStartWord() || IsEndPara();
112
0
    }
113
0
    Push();
114
0
    ClearMark();
115
0
    while( !bRet )
116
0
    {
117
0
        if( !GoPrevWord() )
118
0
        {
119
0
            if( (!IsSttPara() && !SwCursorShell::MovePara( GoCurrPara, fnParaStart ) )
120
0
                || !SwCursorShell::Left(1,SwCursorSkipMode::Chars) )
121
0
                break;
122
0
            bRet = IsStartWord();
123
0
        }
124
0
        else
125
0
            bRet = true;
126
0
    }
127
0
    ClearMark();
128
0
    Combine();
129
0
    return bRet;
130
0
}
131
132
// #i92468#
133
// method code of <SwWrtShell::NxtWrd_()> before fix for issue i72162
134
bool SwWrtShell::NxtWrdForDelete()
135
0
{
136
0
    if ( IsEndPara() )
137
0
    {
138
0
        if ( !SwCursorShell::Right(1,SwCursorSkipMode::Chars) )
139
0
        {
140
0
            Pop(SwCursorShell::PopMode::DeleteCurrent);
141
0
            return false;
142
0
        }
143
0
        return true;
144
0
    }
145
0
    Push();
146
0
    ClearMark();
147
0
    if ( !GoNextWord() )
148
0
    {
149
0
        SwCursorShell::MovePara( GoCurrPara, fnParaEnd );
150
0
    }
151
0
    ClearMark();
152
0
    Combine();
153
0
    return true;
154
0
}
155
156
// method code of <SwWrtShell::PrvWrd_()> before fix for issue i72162
157
bool SwWrtShell::PrvWrdForDelete()
158
0
{
159
0
    if ( IsSttPara() )
160
0
    {
161
0
        if ( !SwCursorShell::Left(1,SwCursorSkipMode::Chars) )
162
0
        {
163
0
            Pop(SwCursorShell::PopMode::DeleteCurrent);
164
0
            return false;
165
0
        }
166
0
        return true;
167
0
    }
168
0
    Push();
169
0
    ClearMark();
170
0
    if( !GoPrevWord() )
171
0
    {
172
0
        SwCursorShell::MovePara( GoCurrPara, fnParaStart );
173
0
    }
174
0
    ClearMark();
175
0
    Combine();
176
0
    return true;
177
0
}
178
179
bool SwWrtShell::FwdSentence_()
180
0
{
181
0
    Push();
182
0
    ClearMark();
183
0
    if(!SwCursorShell::Right(1,SwCursorSkipMode::Chars))
184
0
    {
185
0
        Pop(SwCursorShell::PopMode::DeleteCurrent);
186
0
        return false;
187
0
    }
188
0
    if( !GoNextSentence() && !IsEndPara() )
189
0
        SwCursorShell::MovePara(GoCurrPara, fnParaEnd);
190
191
0
    ClearMark();
192
0
    Combine();
193
0
    return true;
194
0
}
195
196
bool SwWrtShell::BwdSentence_()
197
0
{
198
0
    Push();
199
0
    ClearMark();
200
0
    if(!SwCursorShell::Left(1,SwCursorSkipMode::Chars))
201
0
    {
202
0
        Pop(SwCursorShell::PopMode::DeleteCurrent);
203
0
        return false;
204
0
    }
205
0
    if( !GoStartSentence()  && !IsSttPara() )
206
            // not found --> go to the beginning of the paragraph
207
0
        SwCursorShell::MovePara( GoCurrPara, fnParaStart );
208
0
    ClearMark();
209
0
    Combine();
210
0
    return true;
211
0
}
212
213
bool SwWrtShell::FwdPara_()
214
0
{
215
0
    Push();
216
0
    ClearMark();
217
0
    bool bRet = SwCursorShell::MovePara(GoNextPara, fnParaStart);
218
219
0
    ClearMark();
220
0
    Combine();
221
0
    return bRet;
222
0
}
223
224
bool SwWrtShell::BwdPara_()
225
0
{
226
0
    Push();
227
0
    ClearMark();
228
229
0
    bool bRet = SwCursorShell::MovePara(GoPrevPara, fnParaStart);
230
0
    if ( !bRet && !IsSttOfPara() )
231
0
    {
232
0
        SttPara();
233
0
    }
234
235
0
    ClearMark();
236
0
    Combine();
237
0
    return bRet;
238
0
}
239
240
std::optional<OString> SwWrtShell::getLOKPayload(int nType, int nViewId) const
241
0
{
242
0
    switch(nType)
243
0
    {
244
0
        case LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR:
245
0
        case LOK_CALLBACK_INVALIDATE_VIEW_CURSOR:
246
0
            return GetVisibleCursor()->getLOKPayload(nType, nViewId);
247
0
        case LOK_CALLBACK_TEXT_SELECTION:
248
0
        case LOK_CALLBACK_TEXT_VIEW_SELECTION:
249
0
        {
250
            // Aggregate selection rectangles from all cursors in the ring.
251
            // In add mode (CTRL+click multi-selection), the actual selections
252
            // are stored in ring cursors, while m_pCurrentCursor may be empty.
253
            // Without aggregation, callback only reads from m_pCurrentCursor and send an empty payload,
254
            // clearing the selection on the online side.
255
0
            std::vector<OString> aAllRects;
256
0
            for (const SwPaM& rPaM : GetCursor_()->GetRingContainer())
257
0
            {
258
0
                const SwShellCursor* pShCursor = dynamic_cast<const SwShellCursor*>(&rPaM);
259
0
                if (!pShCursor)
260
0
                    continue;
261
0
                for (size_t i = 0; i < pShCursor->size(); ++i)
262
0
                {
263
0
                    const SwRect& rRect = (*pShCursor)[i];
264
0
                    aAllRects.push_back(rRect.SVRect().toString());
265
0
                }
266
0
            }
267
0
            OString sRect = comphelper::string::join("; ", aAllRects);
268
0
            if (nType == LOK_CALLBACK_TEXT_SELECTION)
269
0
                return sRect;
270
0
            else // LOK_CALLBACK_TEXT_VIEW_SELECTION
271
0
                return SfxLokHelper::makePayloadJSON(GetSfxViewShell(), nViewId, "selection", sRect);
272
0
        }
273
0
        case LOK_CALLBACK_TEXT_SELECTION_START:
274
0
        case LOK_CALLBACK_TEXT_SELECTION_END:
275
0
            return GetCursor_()->getLOKPayload(nType);
276
0
    }
277
0
    abort();
278
0
}
279
280
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */