Coverage Report

Created: 2026-07-10 11:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sw/source/uibase/dochdl/gloshdl.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 <utility>
21
#include <vcl/errinf.hxx>
22
#include <vcl/weld/MessageDialog.hxx>
23
#include <svl/macitem.hxx>
24
#include <sfx2/fcontnr.hxx>
25
#include <sfx2/docfile.hxx>
26
#include <sfx2/docfilt.hxx>
27
#include <tools/urlobj.hxx>
28
#include <unotools/transliterationwrapper.hxx>
29
#include <o3tl/string_view.hxx>
30
#include <docsh.hxx>
31
#include <wrtsh.hxx>
32
#include <view.hxx>
33
#include <gloshdl.hxx>
34
#include <glosdoc.hxx>
35
#include <shellio.hxx>
36
#include <swundo.hxx>
37
#include <expfld.hxx>
38
#include <initui.hxx>
39
#include <gloslst.hxx>
40
#include <swdtflvr.hxx>
41
42
#include <strings.hrc>
43
#include <vcl/svapp.hxx>
44
#include <osl/diagnose.h>
45
46
#include <editeng/acorrcfg.hxx>
47
#include <sfx2/event.hxx>
48
#include <swabstdlg.hxx>
49
50
#include <memory>
51
52
using namespace ::com::sun::star;
53
54
const short RET_EDIT = 100;
55
56
namespace {
57
58
struct TextBlockInfo_Impl
59
{
60
    OUString sTitle;
61
    OUString sLongName;
62
    OUString sGroupName;
63
    TextBlockInfo_Impl(OUString aTitle, OUString aLongName, OUString aGroupName)
64
0
        : sTitle(std::move(aTitle)), sLongName(std::move(aLongName)), sGroupName(std::move(aGroupName)) {}
65
};
66
67
}
68
69
// Dialog for edit templates
70
void SwGlossaryHdl::GlossaryDlg()
71
0
{
72
0
    SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
73
0
    VclPtr<AbstractGlossaryDlg> pDlg(pFact->CreateGlossaryDlg(m_rViewFrame, this, m_pWrtShell));
74
75
0
    pDlg->StartExecuteAsync(
76
0
        [this, pDlg] (sal_Int32 nResult)->void
77
0
        {
78
0
            OUString sName;
79
0
            OUString sShortName;
80
0
            if (nResult == RET_OK)
81
0
                pDlg->Apply();
82
0
            if (nResult == RET_EDIT)
83
0
            {
84
0
                sName = pDlg->GetCurrGrpName();
85
0
                sShortName = pDlg->GetCurrShortName();
86
0
            }
87
0
            pDlg->disposeOnce();
88
0
            m_pCurGrp.reset();
89
0
            if(HasGlossaryList())
90
0
            {
91
0
                GetGlossaryList()->ClearGroups();
92
0
            }
93
94
0
            if( !sName.isEmpty() || !sShortName.isEmpty() )
95
0
                m_rStatGlossaries.EditGroupDoc( sName, sShortName );
96
97
0
            SwGlossaryList* pList = ::GetGlossaryList();
98
0
            if(pList->IsActive())
99
0
                pList->Update();
100
0
        }
101
0
    );
102
0
}
103
104
// set the default group; if called from the dialog
105
// the group is created temporarily for faster access
106
void SwGlossaryHdl::SetCurGroup(const OUString &rGrp, bool bApi, bool bAlwaysCreateNew )
107
0
{
108
0
    OUString sGroup(rGrp);
109
0
    if (sGroup.indexOf(GLOS_DELIM)<0 && !FindGroupName(sGroup))
110
0
    {
111
0
        sGroup += OUStringChar(GLOS_DELIM) + "0";
112
0
    }
113
0
    if(m_pCurGrp)
114
0
    {
115
0
        bool bPathEqual = false;
116
0
        if(!bAlwaysCreateNew)
117
0
        {
118
0
            INetURLObject aTemp( m_pCurGrp->GetFileName() );
119
0
            const OUString sCurBase = aTemp.getBase();
120
0
            aTemp.removeSegment();
121
0
            const OUString sCurEntryPath = aTemp.GetMainURL(INetURLObject::DecodeMechanism::NONE);
122
0
            const std::vector<OUString> & rPathArr = m_rStatGlossaries.GetPathArray();
123
0
            sal_uInt16 nCurrentPath = USHRT_MAX;
124
0
            for (size_t nPath = 0; nPath < rPathArr.size(); ++nPath)
125
0
            {
126
0
                if (sCurEntryPath == rPathArr[nPath])
127
0
                {
128
0
                    nCurrentPath = o3tl::narrowing<sal_uInt16>(nPath);
129
0
                    break;
130
0
                }
131
0
            }
132
0
            const std::u16string_view sPath = o3tl::getToken(sGroup, 1, GLOS_DELIM);
133
0
            sal_uInt16 nComparePath = o3tl::narrowing<sal_uInt16>(o3tl::toInt32(sPath));
134
0
            if(nCurrentPath == nComparePath &&
135
0
                o3tl::getToken(sGroup, 0, GLOS_DELIM) == sCurBase)
136
0
                bPathEqual = true;
137
0
        }
138
139
        // When path changed, the name is not reliable
140
0
        if(!bAlwaysCreateNew && bPathEqual)
141
0
            return;
142
0
    }
143
0
    m_aCurGrp = sGroup;
144
0
    if(!bApi)
145
0
    {
146
0
        m_pCurGrp = m_rStatGlossaries.GetGroupDoc(m_aCurGrp, true);
147
0
    }
148
0
}
149
150
size_t SwGlossaryHdl::GetGroupCnt() const
151
0
{
152
0
    return m_rStatGlossaries.GetGroupCnt();
153
0
}
154
155
OUString SwGlossaryHdl::GetGroupName( size_t nId, OUString* pTitle )
156
0
{
157
0
    OUString sRet = m_rStatGlossaries.GetGroupName(nId);
158
0
    if(pTitle)
159
0
    {
160
0
        std::unique_ptr<SwTextBlocks> pGroup = m_rStatGlossaries.GetGroupDoc(sRet);
161
0
        if (pGroup && !pGroup->GetError())
162
0
        {
163
0
            *pTitle = pGroup->GetName();
164
0
            if (pTitle->isEmpty())
165
0
            {
166
0
                *pTitle = sRet.getToken(0, GLOS_DELIM);
167
0
                pGroup->SetName(*pTitle);
168
0
            }
169
0
        }
170
0
        else
171
0
        {
172
0
            sRet.clear();
173
0
        }
174
0
    }
175
0
    return sRet;
176
0
}
177
178
void SwGlossaryHdl::NewGroup(OUString &rGrpName, const OUString& rTitle)
179
0
{
180
0
    if (rGrpName.indexOf(GLOS_DELIM)<0)
181
0
        FindGroupName(rGrpName);
182
0
    m_rStatGlossaries.NewGroupDoc(rGrpName, rTitle);
183
0
}
184
185
void SwGlossaryHdl::RenameGroup(const OUString& rOld, OUString& rNew, const OUString& rNewTitle)
186
0
{
187
0
    OUString sOldGroup(rOld);
188
0
    if (rOld.indexOf(GLOS_DELIM)<0)
189
0
        FindGroupName(sOldGroup);
190
0
    if(rOld == rNew)
191
0
    {
192
0
        std::unique_ptr<SwTextBlocks> pGroup = m_rStatGlossaries.GetGroupDoc(sOldGroup);
193
0
        if(pGroup)
194
0
        {
195
0
            pGroup->SetName(rNewTitle);
196
0
        }
197
0
    }
198
0
    else
199
0
    {
200
0
        OUString sNewGroup(rNew);
201
0
        if (sNewGroup.indexOf(GLOS_DELIM)<0)
202
0
        {
203
0
            sNewGroup += OUStringChar(GLOS_DELIM) + "0";
204
0
        }
205
0
        m_rStatGlossaries.RenameGroupDoc(sOldGroup, sNewGroup, rNewTitle);
206
0
        rNew = sNewGroup;
207
0
    }
208
0
}
209
210
bool SwGlossaryHdl::CopyOrMove(const OUString& rSourceGroupName, OUString& rSourceShortName,
211
                               const OUString& rDestGroupName, const OUString& rLongName, bool bMove)
212
0
{
213
0
    std::unique_ptr<SwTextBlocks> pSourceGroup = m_rStatGlossaries.GetGroupDoc(rSourceGroupName);
214
0
    std::unique_ptr<SwTextBlocks> pDestGroup = m_rStatGlossaries.GetGroupDoc(rDestGroupName);
215
0
    if (pDestGroup->IsReadOnly() || (bMove && pSourceGroup->IsReadOnly()) )
216
0
    {
217
0
        return false;
218
0
    }
219
220
    //The index must be determined here because rSourceShortName maybe changed in CopyBlock
221
0
    sal_uInt16 nDeleteIdx = pSourceGroup->GetIndex( rSourceShortName );
222
0
    OSL_ENSURE(USHRT_MAX != nDeleteIdx, "entry not found");
223
0
    ErrCode nRet = pSourceGroup->CopyBlock( *pDestGroup, rSourceShortName, rLongName );
224
0
    if(!nRet && bMove)
225
0
    {
226
        // the index must be existing
227
0
        nRet = pSourceGroup->Delete( nDeleteIdx ) ? ERRCODE_NONE : ErrCode(1);
228
0
    }
229
0
    return !nRet;
230
0
}
231
232
// delete an autotext-file-group
233
bool SwGlossaryHdl::DelGroup(const OUString &rGrpName)
234
0
{
235
0
    OUString sGroup(rGrpName);
236
0
    if (sGroup.indexOf(GLOS_DELIM)<0)
237
0
        FindGroupName(sGroup);
238
0
    if( m_rStatGlossaries.DelGroupDoc(sGroup) )
239
0
    {
240
0
        if(m_pCurGrp)
241
0
        {
242
0
            if (m_pCurGrp->GetName() == sGroup)
243
0
                m_pCurGrp.reset();
244
0
        }
245
0
        return true;
246
0
    }
247
0
    return false;
248
0
}
249
250
// ask for number of autotexts
251
sal_uInt16 SwGlossaryHdl::GetGlossaryCnt() const
252
0
{
253
0
    return m_pCurGrp ? m_pCurGrp->GetCount() : 0;
254
0
}
255
256
const OUString & SwGlossaryHdl::GetGlossaryName( sal_uInt16 nId )
257
0
{
258
0
    OSL_ENSURE(nId < GetGlossaryCnt(), "Text building block array over-indexed.");
259
0
    return m_pCurGrp->GetLongName( nId );
260
0
}
261
262
const OUString & SwGlossaryHdl::GetGlossaryShortName(sal_uInt16 nId)
263
0
{
264
0
    OSL_ENSURE(nId < GetGlossaryCnt(), "Text building block array over-indexed.");
265
0
    return m_pCurGrp->GetShortName( nId );
266
0
}
267
268
// ask for short name
269
OUString SwGlossaryHdl::GetGlossaryShortName(std::u16string_view aName)
270
0
{
271
0
    OUString sReturn;
272
0
    SwTextBlocks *pTmp =
273
0
        m_pCurGrp ? m_pCurGrp.get() : m_rStatGlossaries.GetGroupDoc( m_aCurGrp ).release();
274
0
    if(pTmp)
275
0
    {
276
0
        sal_uInt16 nIdx = pTmp->GetLongIndex( aName );
277
0
        if( nIdx != sal_uInt16(-1) )
278
0
            sReturn = pTmp->GetShortName( nIdx );
279
0
        if( !m_pCurGrp )
280
0
            delete pTmp;
281
0
    }
282
0
    return sReturn;
283
0
}
284
285
// short name for autotext already used?
286
bool SwGlossaryHdl::HasShortName(const OUString& rShortName) const
287
0
{
288
0
    SwTextBlocks *pBlock = m_pCurGrp ? m_pCurGrp.get()
289
0
                                   : m_rStatGlossaries.GetGroupDoc( m_aCurGrp ).release();
290
0
    bool bRet = pBlock->GetIndex( rShortName ) != sal_uInt16(-1);
291
0
    if( !m_pCurGrp )
292
0
        delete pBlock;
293
0
    return bRet;
294
0
}
295
296
// Create autotext
297
bool SwGlossaryHdl::NewGlossary(const OUString& rName, const OUString& rShortName,
298
                                bool bCreateGroup, bool bNoAttr)
299
0
{
300
0
    SwTextBlocks *pTmp =
301
0
        m_pCurGrp ? m_pCurGrp.get() : m_rStatGlossaries.GetGroupDoc( m_aCurGrp, bCreateGroup ).release();
302
    //pTmp == 0 if the AutoText path setting is wrong
303
0
    if(!pTmp)
304
0
    {
305
0
        if (!m_pCurGrp)
306
0
            delete pTmp;
307
0
        return false;
308
0
    }
309
310
0
    OUString sOnlyText;
311
0
    OUString* pOnlyText = nullptr;
312
0
    if( bNoAttr )
313
0
    {
314
0
        m_pWrtShell->GetSelectedText( sOnlyText, ParaBreakType::ToOnlyCR );
315
0
        pOnlyText = &sOnlyText;
316
0
    }
317
318
0
    const SvxAutoCorrCfg& rCfg = SvxAutoCorrCfg::Get();
319
320
0
    const sal_uInt16 nSuccess = m_pWrtShell->MakeGlossary( *pTmp, rName, rShortName,
321
0
                            rCfg.IsSaveRelFile(), pOnlyText );
322
0
    if(nSuccess == sal_uInt16(-1) )
323
0
    {
324
0
        std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_pWrtShell->GetView().GetFrameWeld(),
325
0
                                                                                   VclMessageType::Info, VclButtonsType::Ok, SwResId(STR_ERR_INSERT_GLOS)));
326
0
        xBox->run();
327
0
    }
328
0
    if( !m_pCurGrp )
329
0
        delete pTmp;
330
0
    return nSuccess != sal_uInt16(-1);
331
0
}
332
333
// Delete an autotext
334
bool SwGlossaryHdl::DelGlossary(const OUString &rShortName)
335
0
{
336
0
    SwTextBlocks *pGlossary = m_pCurGrp ? m_pCurGrp.get()
337
0
                                    : m_rStatGlossaries.GetGroupDoc(m_aCurGrp).release();
338
    //pTmp == 0 if the AutoText path setting is wrong
339
0
    if(!pGlossary)
340
0
    {
341
0
        if( !m_pCurGrp )
342
0
            delete pGlossary;
343
0
        return false;
344
0
    }
345
346
0
    sal_uInt16 nIdx = pGlossary->GetIndex( rShortName );
347
0
    if( nIdx != sal_uInt16(-1) )
348
0
        pGlossary->Delete( nIdx );
349
0
    if( !m_pCurGrp )
350
0
        delete pGlossary;
351
0
    return true;
352
0
}
353
354
// expand short name
355
bool SwGlossaryHdl::ExpandGlossary(weld::Window* pParent)
356
0
{
357
0
    OSL_ENSURE(m_pWrtShell->CanInsert(), "illegal");
358
0
    SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
359
0
    ::GlossaryGetCurrGroup fnGetCurrGroup = pFact->GetGlossaryCurrGroupFunc();
360
0
    OUString sGroupName( (*fnGetCurrGroup)() );
361
0
    if (sGroupName.indexOf(GLOS_DELIM)<0)
362
0
        FindGroupName(sGroupName);
363
0
    std::unique_ptr<SwTextBlocks> pGlossary = m_rStatGlossaries.GetGroupDoc(sGroupName);
364
365
0
    OUString aShortName;
366
367
        // use this at text selection
368
0
    if(m_pWrtShell->SwCursorShell::HasSelection() && !m_pWrtShell->IsBlockMode())
369
0
    {
370
0
        aShortName = m_pWrtShell->GetSelText();
371
0
    }
372
0
    else
373
0
    {
374
0
        if(m_pWrtShell->IsAddMode())
375
0
            m_pWrtShell->LeaveAddMode();
376
0
        else if(m_pWrtShell->IsBlockMode())
377
0
            m_pWrtShell->LeaveBlockMode();
378
0
        else if(m_pWrtShell->IsExtMode())
379
0
            m_pWrtShell->LeaveExtMode();
380
        // select word (tdf#126589: part to the left of cursor)
381
0
        if (m_pWrtShell->IsInWord() || m_pWrtShell->IsEndWrd())
382
0
            m_pWrtShell->PrvWrd(true);
383
            // ask for word
384
0
        if(m_pWrtShell->IsSelection())
385
0
            aShortName = m_pWrtShell->GetSelText();
386
0
    }
387
0
    return Expand(pParent, aShortName, &m_rStatGlossaries, std::move(pGlossary));
388
0
}
389
390
bool SwGlossaryHdl::Expand(weld::Window* pParent, const OUString& rShortName,
391
                            SwGlossaries *pGlossaries,
392
                            std::unique_ptr<SwTextBlocks> pGlossary)
393
0
{
394
0
    std::vector<TextBlockInfo_Impl> aFoundArr;
395
0
    OUString aShortName( rShortName );
396
0
    bool bCancel = false;
397
    // search for text block
398
    // - don't prefer current group depending on configuration setting
399
0
    const SvxAutoCorrCfg& rCfg = SvxAutoCorrCfg::Get();
400
0
    sal_uInt16 nFound = (!rCfg.IsSearchInAllCategories() && pGlossary) ?
401
0
        pGlossary->GetIndex( aShortName ) : USHRT_MAX;
402
    // if not found then search in all groups
403
0
    if (nFound == USHRT_MAX)
404
0
    {
405
0
        const ::utl::TransliterationWrapper& rSCmp = GetAppCmpStrIgnore();
406
0
        SwGlossaryList* pGlossaryList = ::GetGlossaryList();
407
0
        const size_t nGroupCount = pGlossaryList->GetGroupCount();
408
0
        for(size_t i = 0; i < nGroupCount; ++i)
409
0
        {
410
            // get group name with path-extension
411
0
            const OUString sGroupName = pGlossaryList->GetGroupName(i);
412
0
            if (pGlossary && sGroupName == pGlossary->GetName())
413
0
                continue;
414
0
            const sal_uInt16 nBlockCount = pGlossaryList->GetBlockCount(i);
415
0
            if(nBlockCount)
416
0
            {
417
0
                const OUString sTitle = pGlossaryList->GetGroupTitle(i);
418
0
                for(sal_uInt16 j = 0; j < nBlockCount; j++)
419
0
                {
420
0
                    const OUString sLongName(pGlossaryList->GetBlockLongName(i, j));
421
0
                    const OUString sShortName(pGlossaryList->GetBlockShortName(i, j));
422
0
                    if( rSCmp.isEqual( rShortName, sShortName ))
423
0
                    {
424
0
                        aFoundArr.emplace_back(sTitle, sLongName, sGroupName);
425
0
                    }
426
0
                }
427
0
            }
428
0
        }
429
0
        if( !aFoundArr.empty() )  // one was found
430
0
        {
431
0
            pGlossary.reset();
432
0
            if (1 == aFoundArr.size())
433
0
            {
434
0
                TextBlockInfo_Impl& rData = aFoundArr.front();
435
0
                pGlossary = pGlossaries->GetGroupDoc(rData.sGroupName);
436
0
                nFound = pGlossary->GetIndex( aShortName );
437
0
            }
438
0
            else
439
0
            {
440
0
                SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
441
0
                ScopedVclPtr<AbstractSwSelGlossaryDlg> pDlg(pFact->CreateSwSelGlossaryDlg(pParent, aShortName));
442
0
                for(const TextBlockInfo_Impl & i : aFoundArr)
443
0
                {
444
0
                    if (i.sTitle == "My AutoText")
445
0
                        pDlg->InsertGlos(SwResId(STR_MY_AUTOTEXT), i.sLongName);
446
0
                    else
447
0
                        pDlg->InsertGlos(i.sTitle, i.sLongName);
448
0
                }
449
0
                pDlg->SelectEntryPos(0);
450
0
                const sal_Int32 nRet = RET_OK == pDlg->Execute() ?
451
0
                                        pDlg->GetSelectedIdx() :
452
0
                                        -1;
453
0
                pDlg.disposeAndClear();
454
0
                if (nRet != -1)
455
0
                {
456
0
                    TextBlockInfo_Impl& rData = aFoundArr[nRet];
457
0
                    pGlossary = pGlossaries->GetGroupDoc(rData.sGroupName);
458
0
                    nFound = pGlossary->GetIndex( aShortName );
459
0
                }
460
0
                else
461
0
                {
462
0
                    nFound = USHRT_MAX;
463
0
                    bCancel = true;
464
0
                }
465
0
            }
466
0
        }
467
0
    }
468
469
    // not found
470
0
    if (nFound == USHRT_MAX)
471
0
    {
472
0
        if( !bCancel )
473
0
        {
474
0
            pGlossary.reset();
475
476
0
            const sal_Int32 nMaxLen = 50;
477
0
            if(m_pWrtShell->IsSelection() && aShortName.getLength() > nMaxLen)
478
0
            {
479
0
                aShortName = OUString::Concat(aShortName.subView(0, nMaxLen)) + " ...";
480
0
            }
481
0
            OUString aTmp( SwResId(STR_NOGLOS));
482
0
            aTmp = aTmp.replaceFirst("%1", aShortName);
483
0
            std::shared_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(m_pWrtShell->GetView().GetFrameWeld(),
484
0
                                                          VclMessageType::Info, VclButtonsType::Ok,
485
0
                                                          aTmp));
486
0
            xInfoBox->runAsync(xInfoBox, [] (sal_uInt32){ });
487
0
        }
488
489
0
        return false;
490
0
    }
491
0
    else
492
0
    {
493
0
        SvxMacro aStartMacro(OUString(), OUString(), STARBASIC);
494
0
        SvxMacro aEndMacro(OUString(), OUString(), STARBASIC);
495
0
        GetMacros( aShortName, aStartMacro, aEndMacro, pGlossary.get() );
496
497
        // StartAction must not be before HasSelection and DelRight,
498
        // otherwise the possible Shell change gets delayed and
499
        // API-programs would hang.
500
        // Moreover the event macro must also not be called in an action
501
0
        m_pWrtShell->StartUndo(SwUndoId::INSGLOSSARY);
502
0
        if( aStartMacro.HasMacro() )
503
0
            m_pWrtShell->ExecMacro( aStartMacro );
504
0
        if(m_pWrtShell->HasSelection())
505
0
            m_pWrtShell->DelLeft();
506
0
        m_pWrtShell->StartAllAction();
507
508
        // cache all InputFields
509
0
        SwInputFieldList aFieldLst( m_pWrtShell, true );
510
511
0
        m_pWrtShell->InsertGlossary(*pGlossary, aShortName);
512
0
        m_pWrtShell->EndAllAction();
513
0
        if( aEndMacro.HasMacro() )
514
0
        {
515
0
            m_pWrtShell->ExecMacro( aEndMacro );
516
0
        }
517
0
        m_pWrtShell->EndUndo(SwUndoId::INSGLOSSARY);
518
519
        // demand input for all new InputFields
520
0
        if( aFieldLst.BuildSortLst() )
521
0
            m_pWrtShell->UpdateInputFields( &aFieldLst );
522
0
    }
523
0
    return true;
524
0
}
525
526
// add autotext
527
bool SwGlossaryHdl::InsertGlossary(const OUString &rName)
528
0
{
529
0
    OSL_ENSURE(m_pWrtShell->CanInsert(), "illegal");
530
531
0
    SwTextBlocks *pGlos =
532
0
        m_pCurGrp ? m_pCurGrp.get() : m_rStatGlossaries.GetGroupDoc(m_aCurGrp).release();
533
534
0
    if (!pGlos)
535
0
    {
536
0
        if (!m_pCurGrp)
537
0
            delete pGlos;
538
0
        return false;
539
0
    }
540
541
0
    SvxMacro aStartMacro(OUString(), OUString(), STARBASIC);
542
0
    SvxMacro aEndMacro(OUString(), OUString(), STARBASIC);
543
0
    GetMacros( rName, aStartMacro, aEndMacro, pGlos );
544
545
    // StartAction must not be before HasSelection and DelRight,
546
    // otherwise the possible Shell change gets delayed and
547
    // API-programs would hang.
548
    // Moreover the event macro must also not be called in an action
549
0
    if( aStartMacro.HasMacro() )
550
0
        m_pWrtShell->ExecMacro( aStartMacro );
551
0
    if( m_pWrtShell->HasSelection() )
552
0
        m_pWrtShell->DelRight();
553
0
    m_pWrtShell->StartAllAction();
554
555
    // cache all InputFields
556
0
    SwInputFieldList aFieldLst( m_pWrtShell, true );
557
558
0
    m_pWrtShell->InsertGlossary(*pGlos, rName);
559
0
    m_pWrtShell->EndAllAction();
560
0
    if( aEndMacro.HasMacro() )
561
0
    {
562
0
        m_pWrtShell->ExecMacro( aEndMacro );
563
0
    }
564
565
    // demand input for all new InputFields
566
0
    if( aFieldLst.BuildSortLst() )
567
0
        m_pWrtShell->UpdateInputFields( &aFieldLst );
568
569
0
    if(!m_pCurGrp)
570
0
        delete pGlos;
571
0
    return true;
572
0
}
573
574
// set / ask for macro
575
void SwGlossaryHdl::SetMacros(const OUString& rShortName,
576
                              const SvxMacro* pStart,
577
                              const SvxMacro* pEnd,
578
                              SwTextBlocks *pGlossary )
579
0
{
580
0
    SwTextBlocks *pGlos = pGlossary ? pGlossary :
581
0
                                m_pCurGrp ? m_pCurGrp.get()
582
0
                                  : m_rStatGlossaries.GetGroupDoc( m_aCurGrp ).release();
583
0
    SvxMacroTableDtor aMacroTable;
584
0
    if( pStart )
585
0
        aMacroTable.Insert( SvMacroItemId::SwStartInsGlossary, *pStart);
586
0
    if( pEnd )
587
0
        aMacroTable.Insert( SvMacroItemId::SwEndInsGlossary, *pEnd);
588
0
    sal_uInt16 nIdx = pGlos->GetIndex( rShortName );
589
0
    if( !pGlos->SetMacroTable( nIdx, aMacroTable ) && pGlos->GetError() )
590
0
        ErrorHandler::HandleError( pGlos->GetError() );
591
592
0
    if(!m_pCurGrp && !pGlossary)
593
0
        delete pGlos;
594
0
}
595
596
void SwGlossaryHdl::GetMacros( const OUString &rShortName,
597
                                SvxMacro& rStart,
598
                                SvxMacro& rEnd,
599
                                SwTextBlocks *pGlossary  )
600
0
{
601
0
    SwTextBlocks *pGlos = pGlossary ? pGlossary
602
0
                                    : m_pCurGrp ? m_pCurGrp.get()
603
0
                                        : m_rStatGlossaries.GetGroupDoc(m_aCurGrp).release();
604
0
    sal_uInt16 nIndex = pGlos->GetIndex( rShortName );
605
0
    if( nIndex != USHRT_MAX )
606
0
    {
607
0
        SvxMacroTableDtor aMacroTable;
608
0
        if( pGlos->GetMacroTable( nIndex, aMacroTable ) )
609
0
        {
610
0
            SvxMacro *pMacro = aMacroTable.Get( SvMacroItemId::SwStartInsGlossary );
611
0
            if( pMacro )
612
0
                rStart = *pMacro;
613
614
0
            pMacro = aMacroTable.Get( SvMacroItemId::SwEndInsGlossary );
615
0
            if( pMacro )
616
0
                rEnd = *pMacro;
617
0
        }
618
0
    }
619
620
0
    if( !m_pCurGrp && !pGlossary )
621
0
        delete pGlos;
622
0
}
623
624
// ctor, dtor
625
SwGlossaryHdl::SwGlossaryHdl(SfxViewFrame& rVwFrame, SwWrtShell *pSh)
626
0
    : m_rStatGlossaries( *::GetGlossaries() ),
627
0
    m_aCurGrp( SwGlossaries::GetDefName() ),
628
0
    m_rViewFrame(rVwFrame),
629
0
    m_pWrtShell( pSh )
630
0
{
631
0
}
632
633
SwGlossaryHdl::~SwGlossaryHdl()
634
0
{
635
0
}
636
637
// rename an autotext
638
bool SwGlossaryHdl::Rename(const OUString& rOldShort, const OUString& rNewShortName,
639
                           const OUString& rNewName )
640
0
{
641
0
    bool bRet = false;
642
0
    SwTextBlocks *pGlossary = m_pCurGrp ? m_pCurGrp.get()
643
0
                                    : m_rStatGlossaries.GetGroupDoc(m_aCurGrp).release();
644
0
    if(pGlossary)
645
0
    {
646
0
        sal_uInt16 nIdx = pGlossary->GetIndex( rOldShort );
647
0
        sal_uInt16 nOldLongIdx = pGlossary->GetLongIndex( rNewName );
648
0
        sal_uInt16 nOldIdx = pGlossary->GetIndex( rNewShortName );
649
650
0
        if( nIdx != USHRT_MAX &&
651
0
                (nOldLongIdx == USHRT_MAX || nOldLongIdx == nIdx )&&
652
0
                    (nOldIdx == USHRT_MAX || nOldIdx == nIdx ))
653
0
        {
654
0
            pGlossary->Rename( nIdx, &rNewShortName, &rNewName );
655
0
            bRet = pGlossary->GetError() == ERRCODE_NONE;
656
0
        }
657
0
        if( !m_pCurGrp )
658
0
            delete pGlossary;
659
0
    }
660
0
    return bRet;
661
0
}
662
663
bool SwGlossaryHdl::IsReadOnly( const OUString* pGrpNm ) const
664
0
{
665
0
    SwTextBlocks *pGlossary = nullptr;
666
667
0
    if (pGrpNm)
668
0
        pGlossary = m_rStatGlossaries.GetGroupDoc( *pGrpNm ).release();
669
0
    else if (m_pCurGrp)
670
0
        pGlossary = m_pCurGrp.get();
671
0
    else
672
0
        pGlossary = m_rStatGlossaries.GetGroupDoc(m_aCurGrp).release();
673
674
0
    const bool bRet = !pGlossary || pGlossary->IsReadOnly();
675
0
    if( pGrpNm || !m_pCurGrp )
676
0
        delete pGlossary;
677
0
    return bRet;
678
0
}
679
680
bool SwGlossaryHdl::IsOld() const
681
0
{
682
0
    if( !m_pCurGrp )
683
0
        m_rStatGlossaries.GetGroupDoc(m_aCurGrp).reset();
684
0
    return false;
685
0
}
686
687
// find group without path index
688
bool SwGlossaryHdl::FindGroupName(OUString& rGroup)
689
0
{
690
0
    return m_rStatGlossaries.FindGroupName(rGroup);
691
0
}
692
693
bool SwGlossaryHdl::CopyToClipboard(SwWrtShell& rSh, const OUString& rShortName)
694
0
{
695
0
    SwTextBlocks *pGlossary = m_pCurGrp ? m_pCurGrp.get()
696
0
                                    : m_rStatGlossaries.GetGroupDoc(m_aCurGrp).release();
697
698
0
    rtl::Reference<SwTransferable> pTransfer = new SwTransferable( rSh );
699
700
0
    bool bRet = pTransfer->CopyGlossary( *pGlossary, rShortName );
701
0
    if( !m_pCurGrp )
702
0
        delete pGlossary;
703
0
    return bRet;
704
0
}
705
706
bool SwGlossaryHdl::ImportGlossaries( const OUString& rName )
707
0
{
708
0
    bool bRet = false;
709
0
    if( !rName.isEmpty() )
710
0
    {
711
0
        std::shared_ptr<const SfxFilter> pFilter;
712
0
        SfxMedium aMed( rName, StreamMode::READ, nullptr, nullptr );
713
0
        SfxFilterMatcher aMatcher( u"swriter"_ustr );
714
0
        aMed.UseInteractionHandler( true );
715
0
        if (aMatcher.GuessFilter(aMed, pFilter, SfxFilterFlags::NONE) == ERRCODE_NONE)
716
0
        {
717
0
            assert(pFilter && "success means pFilter was set");
718
0
            SwTextBlocks *pGlossary = nullptr;
719
0
            aMed.SetFilter( pFilter );
720
0
            Reader* pR = SwReaderWriter::GetReader( pFilter->GetUserData() );
721
0
            if( pR && nullptr != ( pGlossary = m_pCurGrp ? m_pCurGrp.get()
722
0
                                    : m_rStatGlossaries.GetGroupDoc(m_aCurGrp).release()) )
723
0
            {
724
0
                SwReader aReader( aMed, rName );
725
0
                if( aReader.HasGlossaries( *pR ) )
726
0
                {
727
0
                    const SvxAutoCorrCfg& rCfg = SvxAutoCorrCfg::Get();
728
0
                    bRet = aReader.ReadGlossaries( *pR, *pGlossary,
729
0
                                rCfg.IsSaveRelFile() );
730
0
                }
731
732
0
                if (!m_pCurGrp)
733
0
                    delete pGlossary;
734
0
            }
735
0
        }
736
0
    }
737
0
    return bRet;
738
0
}
739
740
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */