Coverage Report

Created: 2025-11-16 09:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sd/source/ui/docshell/docshel3.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 <DrawDocShell.hxx>
21
22
#include <svx/svxids.hrc>
23
24
#include <svx/ofaitem.hxx>
25
#include <svl/stritem.hxx>
26
#include <svl/srchitem.hxx>
27
#include <svl/languageoptions.hxx>
28
#include <svtools/langtab.hxx>
29
#include <sfx2/request.hxx>
30
#include <sfx2/sfxdlg.hxx>
31
#include <sfx2/viewfrm.hxx>
32
#include <vcl/abstdlg.hxx>
33
#include <svx/drawitem.hxx>
34
#include <editeng/langitem.hxx>
35
#include <editeng/eeitem.hxx>
36
#include <editeng/outlobj.hxx>
37
#include <editeng/editobj.hxx>
38
#include <com/sun/star/i18n/TextConversionOption.hpp>
39
#include <sfx2/notebookbar/SfxNotebookBar.hxx>
40
#include <editeng/editeng.hxx>
41
#include <osl/diagnose.h>
42
43
#include <sdmod.hxx>
44
#include <drawdoc.hxx>
45
#include <fusearch.hxx>
46
#include <ViewShell.hxx>
47
#include <slideshow.hxx>
48
#include <fuhhconv.hxx>
49
#include <memory>
50
51
using namespace ::com::sun::star;
52
53
namespace sd {
54
55
static void lcl_setLanguageForObj( SdrObject *pObj, LanguageType nLang, bool bLanguageNone )
56
0
{
57
0
    const sal_uInt16 aLangWhichId_EE[3] =
58
0
    {
59
0
        EE_CHAR_LANGUAGE,
60
0
        EE_CHAR_LANGUAGE_CJK,
61
0
        EE_CHAR_LANGUAGE_CTL
62
0
    };
63
64
0
    if( bLanguageNone )
65
0
        nLang = LANGUAGE_NONE;
66
67
0
    if( nLang != LANGUAGE_DONTKNOW )
68
0
    {
69
0
        if( nLang == LANGUAGE_NONE )
70
0
        {
71
0
            for(sal_uInt16 n : aLangWhichId_EE)
72
0
                pObj->SetMergedItem( SvxLanguageItem( nLang, n ) );
73
0
        }
74
0
        else
75
0
        {
76
0
            sal_uInt16 nLangWhichId = 0;
77
0
            SvtScriptType nScriptType = SvtLanguageOptions::GetScriptTypeOfLanguage( nLang );
78
0
            switch (nScriptType)
79
0
            {
80
0
                case SvtScriptType::LATIN :    nLangWhichId = EE_CHAR_LANGUAGE; break;
81
0
                case SvtScriptType::ASIAN :    nLangWhichId = EE_CHAR_LANGUAGE_CJK; break;
82
0
                case SvtScriptType::COMPLEX :  nLangWhichId = EE_CHAR_LANGUAGE_CTL; break;
83
0
                default:
84
0
                    OSL_FAIL("unexpected case" );
85
0
                    return;
86
0
            }
87
0
            pObj->SetMergedItem( SvxLanguageItem( nLang, nLangWhichId ) );
88
89
            // Reset shape text language to default, so it inherits the shape language set above.
90
0
            OutlinerParaObject* pOutliner = pObj->GetOutlinerParaObject();
91
0
            if (pOutliner)
92
0
            {
93
0
                EditTextObject& rEditTextObject
94
0
                    = const_cast<EditTextObject&>(pOutliner->GetTextObject());
95
0
                for (sal_uInt16 n : aLangWhichId_EE)
96
0
                {
97
0
                    rEditTextObject.RemoveCharAttribs(n);
98
0
                }
99
0
            }
100
0
        }
101
0
    }
102
0
    else    // Reset to default
103
0
    {
104
0
        for(sal_uInt16 n : aLangWhichId_EE)
105
0
            pObj->ClearMergedItem( n );
106
0
    }
107
0
}
108
109
static void lcl_setLanguage( const SdDrawDocument *pDoc, std::u16string_view rLanguage, bool bLanguageNone = false )
110
0
{
111
0
    LanguageType nLang = SvtLanguageTable::GetLanguageType( rLanguage );
112
113
    // Do it for SdDrawDocument->SetLanguage as well?
114
115
0
    sal_uInt16 nPageCount = pDoc->GetPageCount();   // Pick All Pages
116
0
    for( sal_uInt16 nPage = 0; nPage < nPageCount; nPage++ )
117
0
    {
118
0
        const SdrPage *pPage = pDoc->GetPage( nPage );
119
0
        for (const rtl::Reference<SdrObject>& pObj : *pPage)
120
0
            if (pObj->GetObjIdentifier() != SdrObjKind::Page)
121
0
                lcl_setLanguageForObj( pObj.get(), nLang, bLanguageNone );
122
0
    }
123
0
}
124
125
/**
126
 * Handles SFX-Requests
127
 */
128
void DrawDocShell::Execute( SfxRequest& rReq )
129
0
{
130
0
    if(mpViewShell && SlideShow::IsRunning( mpViewShell->GetViewShellBase() )
131
0
        && !SlideShow::IsInteractiveSlideshow( mpViewShell->GetViewShellBase() ) ) // IASS
132
0
    {
133
        // during a running presentation no slot will be executed
134
0
        return;
135
0
    }
136
137
0
    switch ( rReq.GetSlot() )
138
0
    {
139
0
        case SID_SEARCH_ITEM:
140
0
        {
141
0
            const SfxItemSet* pReqArgs = rReq.GetArgs();
142
143
0
            if (pReqArgs)
144
0
            {
145
0
                const SvxSearchItem & rSearchItem = pReqArgs->Get(SID_SEARCH_ITEM);
146
147
0
                SdModule::get()->SetSearchItem(std::unique_ptr<SvxSearchItem>(rSearchItem.Clone()));
148
0
            }
149
150
0
            rReq.Done();
151
0
        }
152
0
        break;
153
154
0
        case FID_SEARCH_ON:
155
0
        {
156
            // no action needed
157
0
            rReq.Done();
158
0
        }
159
0
        break;
160
161
0
        case FID_SEARCH_OFF:
162
0
        {
163
0
            if (mpViewShell)
164
0
            {
165
0
                sd::View* pView = mpViewShell->GetView();
166
0
                if (pView)
167
0
                {
168
0
                    auto& rFunctionContext = pView->getSearchContext();
169
0
                    rtl::Reference<FuSearch>& xFuSearch(rFunctionContext.getFunctionSearch());
170
171
0
                    if (xFuSearch.is())
172
0
                    {
173
                        // End Search&Replace in all docshells
174
0
                        SfxObjectShell* pFirstShell = SfxObjectShell::GetFirst();
175
0
                        SfxObjectShell* pShell = pFirstShell;
176
177
0
                        while (pShell)
178
0
                        {
179
0
                            auto pDrawDocShell = dynamic_cast<DrawDocShell*>(pShell);
180
0
                            if (pDrawDocShell)
181
0
                                pDrawDocShell->CancelSearching();
182
183
0
                            pShell = SfxObjectShell::GetNext(*pShell);
184
185
0
                            if (pShell == pFirstShell)
186
0
                                pShell = nullptr;
187
0
                        }
188
189
0
                        rFunctionContext.resetSearchFunction();
190
0
                        Invalidate();
191
0
                        rReq.Done();
192
0
                    }
193
0
                }
194
0
            }
195
0
        }
196
0
        break;
197
198
0
        case FID_SEARCH_NOW:
199
0
        {
200
0
            const SfxItemSet* pReqArgs = rReq.GetArgs();
201
202
0
            if (pReqArgs && mpViewShell)
203
0
            {
204
0
                sd::View* pView = mpViewShell->GetView();
205
0
                if (pView)
206
0
                {
207
0
                    rtl::Reference<FuSearch> & xFuSearch = pView->getSearchContext().getFunctionSearch();
208
209
0
                    if (!xFuSearch.is())
210
0
                    {
211
0
                        xFuSearch = rtl::Reference<FuSearch>(
212
0
                            FuSearch::createPtr(*mpViewShell,
213
0
                                                mpViewShell->GetActiveWindow(),
214
0
                                                pView, *mpDoc, rReq));
215
216
0
                        pView->getSearchContext().setSearchFunction(xFuSearch);
217
0
                    }
218
219
0
                    if (xFuSearch.is())
220
0
                    {
221
0
                        const SvxSearchItem& rSearchItem = pReqArgs->Get(SID_SEARCH_ITEM);
222
223
0
                        SdModule::get()->SetSearchItem(std::unique_ptr<SvxSearchItem>(rSearchItem.Clone()));
224
0
                        xFuSearch->SearchAndReplace(&rSearchItem);
225
0
                    }
226
0
                }
227
0
            }
228
229
0
            rReq.Done();
230
0
        }
231
0
        break;
232
233
0
        case SID_SAVEDOC:
234
0
        case SID_SAVEASDOC:
235
0
        {
236
0
            const SfxPoolItem* pItem = nullptr;
237
0
            bool bCommitChanges = false;
238
0
            const SfxItemSet* pReqArgs = rReq.GetArgs();
239
0
            bool bHasDontTerminateEdit = pReqArgs && pReqArgs->HasItem(FN_PARAM_1, &pItem);
240
0
            if (bHasDontTerminateEdit && pItem)
241
0
                bCommitChanges = !static_cast<const SfxBoolItem*>(pItem)->GetValue();
242
243
0
            if (mpViewShell && bCommitChanges)
244
0
            {
245
0
                SdrView* pView = mpViewShell->GetView();
246
0
                if (pView)
247
0
                    pView->SdrEndTextEdit();
248
0
            }
249
250
0
            ExecuteSlot( rReq, SfxObjectShell::GetStaticInterface() );
251
0
        }
252
0
        break;
253
254
0
        case SID_VERSION:
255
0
        case SID_CLOSEDOC:
256
0
        {
257
0
            ExecuteSlot(rReq, SfxObjectShell::GetStaticInterface());
258
0
        }
259
0
        break;
260
261
0
        case SID_GET_COLORLIST:
262
0
        {
263
0
            const SvxColorListItem* pColItem = GetItem( SID_COLOR_TABLE );
264
0
            const XColorListRef& pList = pColItem->GetColorList();
265
0
            rReq.SetReturnValue( OfaXColorListItem( SID_GET_COLORLIST, pList ) );
266
0
        }
267
0
        break;
268
269
0
        case SID_HANGUL_HANJA_CONVERSION:
270
0
        {
271
0
            if( mpViewShell )
272
0
            {
273
0
                rtl::Reference<FuPoor> aFunc( FuHangulHanjaConversion::Create(*mpViewShell, mpViewShell->GetActiveWindow(), mpViewShell->GetView(), *mpDoc, rReq ) );
274
0
                static_cast< FuHangulHanjaConversion* >( aFunc.get() )->StartConversion( LANGUAGE_KOREAN, LANGUAGE_KOREAN, nullptr, i18n::TextConversionOption::CHARACTER_BY_CHARACTER, true );
275
0
            }
276
0
        }
277
0
        break;
278
279
0
        case SID_CHINESE_CONVERSION:
280
0
        {
281
0
            if( mpViewShell )
282
0
            {
283
0
                rtl::Reference<FuPoor> aFunc( FuHangulHanjaConversion::Create(*mpViewShell, mpViewShell->GetActiveWindow(), mpViewShell->GetView(), *mpDoc, rReq ) );
284
0
                static_cast< FuHangulHanjaConversion* >( aFunc.get() )->StartChineseConversion();
285
0
            }
286
0
        }
287
0
        break;
288
0
        case SID_LANGUAGE_STATUS:
289
0
        {
290
0
            OUString aNewLangTxt;
291
0
            const SfxStringItem* pItem = rReq.GetArg<SfxStringItem>(SID_LANGUAGE_STATUS);
292
0
            if (pItem)
293
0
                aNewLangTxt = pItem->GetValue();
294
295
0
            if (aNewLangTxt == "*" )
296
0
            {
297
                // open the dialog "Tools/Options/Languages and Locales - General"
298
0
                if (mpViewShell)
299
0
                {
300
0
                    SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
301
0
                    ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateVclDialog( mpViewShell->GetFrameWeld(), SID_LANGUAGE_OPTIONS ));
302
0
                    pDlg->Execute();
303
0
                }
304
0
            }
305
0
            else
306
0
            {
307
0
                if( mpViewShell )
308
0
                {
309
                    // setting the new language...
310
0
                    if (!aNewLangTxt.isEmpty())
311
0
                    {
312
0
                        static constexpr OUString aSelectionLangPrefix(u"Current_"_ustr);
313
0
                        static constexpr OUString aParagraphLangPrefix(u"Paragraph_"_ustr);
314
0
                        static constexpr OUString aDocumentLangPrefix(u"Default_"_ustr);
315
316
0
                        bool bSelection = false;
317
0
                        bool bParagraph = false;
318
319
0
                        SdDrawDocument* pDoc = mpViewShell->GetDoc();
320
0
                        sal_Int32 nPos = -1;
321
0
                        if (-1 != (nPos = aNewLangTxt.indexOf( aDocumentLangPrefix )))
322
0
                        {
323
0
                            aNewLangTxt = aNewLangTxt.replaceAt( nPos, aDocumentLangPrefix.getLength(), u"" );
324
325
0
                            if (aNewLangTxt == "LANGUAGE_NONE")
326
0
                                lcl_setLanguage( pDoc, u"", true );
327
0
                            else if (aNewLangTxt == "RESET_LANGUAGES")
328
0
                                lcl_setLanguage( pDoc, u"" );
329
0
                            else
330
0
                                lcl_setLanguage( pDoc, aNewLangTxt );
331
0
                        }
332
0
                        else if (-1 != (nPos = aNewLangTxt.indexOf( aSelectionLangPrefix )))
333
0
                        {
334
0
                            bSelection = true;
335
0
                            aNewLangTxt = aNewLangTxt.replaceAt( nPos, aSelectionLangPrefix.getLength(), u"" );
336
0
                        }
337
0
                        else if (-1 != (nPos = aNewLangTxt.indexOf( aParagraphLangPrefix )))
338
0
                        {
339
0
                            bParagraph = true;
340
0
                            aNewLangTxt = aNewLangTxt.replaceAt( nPos, aParagraphLangPrefix.getLength(), u"" );
341
0
                        }
342
343
0
                        if (bSelection || bParagraph)
344
0
                        {
345
0
                            SdrView* pSdrView = mpViewShell->GetDrawView();
346
0
                            if (!pSdrView)
347
0
                                return;
348
349
0
                            EditView& rEditView = pSdrView->GetTextEditOutlinerView()->GetEditView();
350
0
                            const LanguageType nLangToUse = SvtLanguageTable::GetLanguageType( aNewLangTxt );
351
0
                            SvtScriptType nScriptType = SvtLanguageOptions::GetScriptTypeOfLanguage( nLangToUse );
352
353
0
                            SfxItemSet aAttrs = rEditView.getEditEngine().GetEmptyItemSet();
354
0
                            if (nScriptType == SvtScriptType::LATIN)
355
0
                                aAttrs.Put( SvxLanguageItem( nLangToUse, EE_CHAR_LANGUAGE ) );
356
0
                            if (nScriptType == SvtScriptType::COMPLEX)
357
0
                                aAttrs.Put( SvxLanguageItem( nLangToUse, EE_CHAR_LANGUAGE_CTL ) );
358
0
                            if (nScriptType == SvtScriptType::ASIAN)
359
0
                                aAttrs.Put( SvxLanguageItem( nLangToUse, EE_CHAR_LANGUAGE_CJK ) );
360
0
                            ESelection aOldSel;
361
0
                            if (bParagraph)
362
0
                            {
363
0
                                ESelection aSel = rEditView.GetSelection();
364
0
                                aOldSel = aSel;
365
0
                                aSel.start.nIndex = 0;
366
0
                                aSel.end.nIndex = EE_TEXTPOS_MAX;
367
0
                                rEditView.SetSelection( aSel );
368
0
                            }
369
370
0
                            rEditView.SetAttribs( aAttrs );
371
0
                            if (bParagraph)
372
0
                                rEditView.SetSelection( aOldSel );
373
0
                        }
374
375
0
                        if ( pDoc->GetOnlineSpell() )
376
0
                        {
377
0
                            pDoc->StartOnlineSpelling();
378
0
                        }
379
0
                    }
380
0
                }
381
0
            }
382
0
            Broadcast(SfxHint(SfxHintId::LanguageChanged));
383
0
        }
384
0
        break;
385
0
        case SID_SPELLCHECK_IGNORE_ALL:
386
0
        {
387
0
            if (!mpViewShell)
388
0
                return;
389
0
            SdrView* pSdrView = mpViewShell->GetDrawView();
390
0
            if (!pSdrView)
391
0
                return;
392
393
0
            EditView& rEditView = pSdrView->GetTextEditOutlinerView()->GetEditView();
394
0
            OUString sIgnoreText;
395
0
            const SfxStringItem* pItem2 = rReq.GetArg<SfxStringItem>(FN_PARAM_1);
396
0
            if (pItem2)
397
0
                sIgnoreText = pItem2->GetValue();
398
399
0
            if(sIgnoreText == "Spelling")
400
0
            {
401
0
                ESelection aOldSel = rEditView.GetSelection();
402
0
                rEditView.SpellIgnoreWord();
403
0
                rEditView.SetSelection( aOldSel );
404
0
            }
405
0
        }
406
0
        break;
407
0
        case SID_SPELLCHECK_APPLY_SUGGESTION:
408
0
        {
409
0
            if (!mpViewShell)
410
0
                return;
411
0
            SdrView* pSdrView = mpViewShell->GetDrawView();
412
0
            if (!pSdrView)
413
0
                return;
414
415
0
            EditView& rEditView = pSdrView->GetTextEditOutlinerView()->GetEditView();
416
0
            OUString sApplyText;
417
0
            const SfxStringItem* pItem2 = rReq.GetArg<SfxStringItem>(FN_PARAM_1);
418
0
            if (pItem2)
419
0
                sApplyText = pItem2->GetValue();
420
421
0
            static constexpr OUString sSpellingRule(u"Spelling_"_ustr);
422
0
            sal_Int32 nPos = 0;
423
0
            if(-1 != (nPos = sApplyText.indexOf( sSpellingRule )))
424
0
            {
425
0
                sApplyText = sApplyText.replaceAt(nPos, sSpellingRule.getLength(), u"");
426
0
                rEditView.InsertText( sApplyText );
427
0
            }
428
0
        }
429
0
        break;
430
431
0
        case SID_NOTEBOOKBAR:
432
0
        {
433
0
            const SfxStringItem* pFile = rReq.GetArg<SfxStringItem>( SID_NOTEBOOKBAR );
434
435
0
            if ( mpViewShell )
436
0
            {
437
0
                SfxBindings& rBindings( mpViewShell->GetFrame()->GetBindings() );
438
439
0
                if ( sfx2::SfxNotebookBar::IsActive() )
440
0
                    sfx2::SfxNotebookBar::ExecMethod( rBindings, pFile ? pFile->GetValue() : u""_ustr );
441
0
                else
442
0
                    sfx2::SfxNotebookBar::CloseMethod( rBindings );
443
0
            }
444
0
        }
445
0
        break;
446
447
0
        default:
448
0
        break;
449
0
    }
450
0
}
451
452
} // end of namespace sd
453
454
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */