/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include <utility>
#include <vcl/errinf.hxx>
#include <vcl/weld.hxx>
#include <svl/macitem.hxx>
#include <sfx2/fcontnr.hxx>
#include <sfx2/docfile.hxx>
#include <sfx2/docfilt.hxx>
#include <unotools/transliterationwrapper.hxx>
#include <o3tl/string_view.hxx>
#include <docsh.hxx>
#include <wrtsh.hxx>
#include <view.hxx>
#include <gloshdl.hxx>
#include <glosdoc.hxx>
#include <shellio.hxx>
#include <swundo.hxx>
#include <expfld.hxx>
#include <initui.hxx>
#include <gloslst.hxx>
#include <swdtflvr.hxx>
#include <strings.hrc>
#include <vcl/svapp.hxx>
#include <osl/diagnose.h>
#include <editeng/acorrcfg.hxx>
#include <sfx2/event.hxx>
#include <swabstdlg.hxx>
#include <memory>
using namespace ::com::sun::star;
const short RET_EDIT = 100;
namespace {
struct TextBlockInfo_Impl
{
OUString sTitle;
OUString sLongName;
OUString sGroupName;
TextBlockInfo_Impl(OUString aTitle, OUString aLongName, OUString aGroupName)
: sTitle(std::move(aTitle)), sLongName(std::move(aLongName)), sGroupName(std::move(aGroupName)) {}
};
}
// Dialog for edit templates
void SwGlossaryHdl::GlossaryDlg()
{
SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
VclPtr<AbstractGlossaryDlg> pDlg(pFact->CreateGlossaryDlg(m_rViewFrame, this, m_pWrtShell));
pDlg->StartExecuteAsync(
[this, pDlg] (sal_Int32 nResult)->void
{
OUString sName;
OUString sShortName;
if (nResult == RET_OK)
pDlg->Apply();
if (nResult == RET_EDIT)
{
sName = pDlg->GetCurrGrpName();
sShortName = pDlg->GetCurrShortName();
}
pDlg->disposeOnce();
m_pCurGrp.reset();
if(HasGlossaryList())
{
GetGlossaryList()->ClearGroups();
}
if( !sName.isEmpty() || !sShortName.isEmpty() )
m_rStatGlossaries.EditGroupDoc( sName, sShortName );
SwGlossaryList* pList = ::GetGlossaryList();
if(pList->IsActive())
pList->Update();
}
);
}
// set the default group; if called from the dialog
// the group is created temporarily for faster access
void SwGlossaryHdl::SetCurGroup(const OUString &rGrp, bool bApi, bool bAlwaysCreateNew )
{
OUString sGroup(rGrp);
if (sGroup.indexOf(GLOS_DELIM)<0 && !FindGroupName(sGroup))
{
sGroup += OUStringChar(GLOS_DELIM) + "0";
}
if(m_pCurGrp)
{
bool bPathEqual = false;
if(!bAlwaysCreateNew)
{
INetURLObject aTemp( m_pCurGrp->GetFileName() );
const OUString sCurBase = aTemp.getBase();
aTemp.removeSegment();
const OUString sCurEntryPath = aTemp.GetMainURL(INetURLObject::DecodeMechanism::NONE);
const std::vector<OUString> & rPathArr = m_rStatGlossaries.GetPathArray();
sal_uInt16 nCurrentPath = USHRT_MAX;
for (size_t nPath = 0; nPath < rPathArr.size(); ++nPath)
{
if (sCurEntryPath == rPathArr[nPath])
{
nCurrentPath = o3tl::narrowing<sal_uInt16>(nPath);
break;
}
}
const std::u16string_view sPath = o3tl::getToken(sGroup, 1, GLOS_DELIM);
sal_uInt16 nComparePath = o3tl::narrowing<sal_uInt16>(o3tl::toInt32(sPath));
if(nCurrentPath == nComparePath &&
o3tl::getToken(sGroup, 0, GLOS_DELIM) == sCurBase)
bPathEqual = true;
}
// When path changed, the name is not reliable
if(!bAlwaysCreateNew && bPathEqual)
return;
}
m_aCurGrp = sGroup;
if(!bApi)
{
m_pCurGrp = m_rStatGlossaries.GetGroupDoc(m_aCurGrp, true);
}
}
size_t SwGlossaryHdl::GetGroupCnt() const
{
return m_rStatGlossaries.GetGroupCnt();
}
OUString SwGlossaryHdl::GetGroupName( size_t nId, OUString* pTitle )
{
OUString sRet = m_rStatGlossaries.GetGroupName(nId);
if(pTitle)
{
std::unique_ptr<SwTextBlocks> pGroup = m_rStatGlossaries.GetGroupDoc(sRet);
if (pGroup && !pGroup->GetError())
{
*pTitle = pGroup->GetName();
if (pTitle->isEmpty())
{
*pTitle = sRet.getToken(0, GLOS_DELIM);
pGroup->SetName(*pTitle);
}
}
else
{
sRet.clear();
}
}
return sRet;
}
void SwGlossaryHdl::NewGroup(OUString &rGrpName, const OUString& rTitle)
{
if (rGrpName.indexOf(GLOS_DELIM)<0)
FindGroupName(rGrpName);
m_rStatGlossaries.NewGroupDoc(rGrpName, rTitle);
}
void SwGlossaryHdl::RenameGroup(const OUString& rOld, OUString& rNew, const OUString& rNewTitle)
{
OUString sOldGroup(rOld);
if (rOld.indexOf(GLOS_DELIM)<0)
FindGroupName(sOldGroup);
if(rOld == rNew)
{
std::unique_ptr<SwTextBlocks> pGroup = m_rStatGlossaries.GetGroupDoc(sOldGroup);
if(pGroup)
{
pGroup->SetName(rNewTitle);
}
}
else
{
OUString sNewGroup(rNew);
if (sNewGroup.indexOf(GLOS_DELIM)<0)
{
sNewGroup += OUStringChar(GLOS_DELIM) + "0";
}
m_rStatGlossaries.RenameGroupDoc(sOldGroup, sNewGroup, rNewTitle);
rNew = sNewGroup;
}
}
bool SwGlossaryHdl::CopyOrMove(const OUString& rSourceGroupName, OUString& rSourceShortName,
const OUString& rDestGroupName, const OUString& rLongName, bool bMove)
{
std::unique_ptr<SwTextBlocks> pSourceGroup = m_rStatGlossaries.GetGroupDoc(rSourceGroupName);
std::unique_ptr<SwTextBlocks> pDestGroup = m_rStatGlossaries.GetGroupDoc(rDestGroupName);
if (pDestGroup->IsReadOnly() || (bMove && pSourceGroup->IsReadOnly()) )
{
return false;
}
//The index must be determined here because rSourceShortName maybe changed in CopyBlock
sal_uInt16 nDeleteIdx = pSourceGroup->GetIndex( rSourceShortName );
OSL_ENSURE(USHRT_MAX != nDeleteIdx, "entry not found");
ErrCode nRet = pSourceGroup->CopyBlock( *pDestGroup, rSourceShortName, rLongName );
if(!nRet && bMove)
{
// the index must be existing
nRet = pSourceGroup->Delete( nDeleteIdx ) ? ERRCODE_NONE : ErrCode(1);
}
return !nRet;
}
// delete an autotext-file-group
bool SwGlossaryHdl::DelGroup(const OUString &rGrpName)
{
OUString sGroup(rGrpName);
if (sGroup.indexOf(GLOS_DELIM)<0)
FindGroupName(sGroup);
if( m_rStatGlossaries.DelGroupDoc(sGroup) )
{
if(m_pCurGrp)
{
if (m_pCurGrp->GetName() == sGroup)
m_pCurGrp.reset();
}
return true;
}
return false;
}
// ask for number of autotexts
sal_uInt16 SwGlossaryHdl::GetGlossaryCnt() const
{
return m_pCurGrp ? m_pCurGrp->GetCount() : 0;
}
const OUString & SwGlossaryHdl::GetGlossaryName( sal_uInt16 nId )
{
OSL_ENSURE(nId < GetGlossaryCnt(), "Text building block array over-indexed.");
return m_pCurGrp->GetLongName( nId );
}
const OUString & SwGlossaryHdl::GetGlossaryShortName(sal_uInt16 nId)
{
OSL_ENSURE(nId < GetGlossaryCnt(), "Text building block array over-indexed.");
return m_pCurGrp->GetShortName( nId );
}
// ask for short name
OUString SwGlossaryHdl::GetGlossaryShortName(std::u16string_view aName)
{
OUString sReturn;
SwTextBlocks *pTmp =
m_pCurGrp ? m_pCurGrp.get() : m_rStatGlossaries.GetGroupDoc( m_aCurGrp ).release();
if(pTmp)
{
sal_uInt16 nIdx = pTmp->GetLongIndex( aName );
if( nIdx != sal_uInt16(-1) )
sReturn = pTmp->GetShortName( nIdx );
if( !m_pCurGrp )
delete pTmp;
}
return sReturn;
}
// short name for autotext already used?
bool SwGlossaryHdl::HasShortName(const OUString& rShortName) const
{
SwTextBlocks *pBlock = m_pCurGrp ? m_pCurGrp.get()
: m_rStatGlossaries.GetGroupDoc( m_aCurGrp ).release();
bool bRet = pBlock->GetIndex( rShortName ) != sal_uInt16(-1);
if( !m_pCurGrp )
delete pBlock;
return bRet;
}
// Create autotext
bool SwGlossaryHdl::NewGlossary(const OUString& rName, const OUString& rShortName,
bool bCreateGroup, bool bNoAttr)
{
SwTextBlocks *pTmp =
m_pCurGrp ? m_pCurGrp.get() : m_rStatGlossaries.GetGroupDoc( m_aCurGrp, bCreateGroup ).release();
//pTmp == 0 if the AutoText path setting is wrong
if(!pTmp)
{
if (!m_pCurGrp)
delete pTmp;
return false;
}
OUString sOnlyText;
OUString* pOnlyText = nullptr;
if( bNoAttr )
{
m_pWrtShell->GetSelectedText( sOnlyText, ParaBreakType::ToOnlyCR );
pOnlyText = &sOnlyText;
}
const SvxAutoCorrCfg& rCfg = SvxAutoCorrCfg::Get();
const sal_uInt16 nSuccess = m_pWrtShell->MakeGlossary( *pTmp, rName, rShortName,
rCfg.IsSaveRelFile(), pOnlyText );
if(nSuccess == sal_uInt16(-1) )
{
std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_pWrtShell->GetView().GetFrameWeld(),
VclMessageType::Info, VclButtonsType::Ok, SwResId(STR_ERR_INSERT_GLOS)));
xBox->run();
}
if( !m_pCurGrp )
delete pTmp;
return nSuccess != sal_uInt16(-1);
}
// Delete an autotext
bool SwGlossaryHdl::DelGlossary(const OUString &rShortName)
{
SwTextBlocks *pGlossary = m_pCurGrp ? m_pCurGrp.get()
: m_rStatGlossaries.GetGroupDoc(m_aCurGrp).release();
//pTmp == 0 if the AutoText path setting is wrong
if(!pGlossary)
{
if( !m_pCurGrp )
delete pGlossary;
return false;
}
sal_uInt16 nIdx = pGlossary->GetIndex( rShortName );
if( nIdx != sal_uInt16(-1) )
pGlossary->Delete( nIdx );
if( !m_pCurGrp )
delete pGlossary;
return true;
}
// expand short name
bool SwGlossaryHdl::ExpandGlossary(weld::Window* pParent)
{
OSL_ENSURE(m_pWrtShell->CanInsert(), "illegal");
SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
::GlossaryGetCurrGroup fnGetCurrGroup = pFact->GetGlossaryCurrGroupFunc();
OUString sGroupName( (*fnGetCurrGroup)() );
if (sGroupName.indexOf(GLOS_DELIM)<0)
FindGroupName(sGroupName);
std::unique_ptr<SwTextBlocks> pGlossary = m_rStatGlossaries.GetGroupDoc(sGroupName);
OUString aShortName;
// use this at text selection
if(m_pWrtShell->SwCursorShell::HasSelection() && !m_pWrtShell->IsBlockMode())
{
aShortName = m_pWrtShell->GetSelText();
}
else
{
if(m_pWrtShell->IsAddMode())
m_pWrtShell->LeaveAddMode();
else if(m_pWrtShell->IsBlockMode())
m_pWrtShell->LeaveBlockMode();
else if(m_pWrtShell->IsExtMode())
m_pWrtShell->LeaveExtMode();
// select word (tdf#126589: part to the left of cursor)
if (m_pWrtShell->IsInWord() || m_pWrtShell->IsEndWrd())
m_pWrtShell->PrvWrd(true);
// ask for word
if(m_pWrtShell->IsSelection())
aShortName = m_pWrtShell->GetSelText();
}
return Expand(pParent, aShortName, &m_rStatGlossaries, std::move(pGlossary));
}
bool SwGlossaryHdl::Expand(weld::Window* pParent, const OUString& rShortName,
SwGlossaries *pGlossaries,
std::unique_ptr<SwTextBlocks> pGlossary)
{
std::vector<TextBlockInfo_Impl> aFoundArr;
OUString aShortName( rShortName );
bool bCancel = false;
// search for text block
// - don't prefer current group depending on configuration setting
const SvxAutoCorrCfg& rCfg = SvxAutoCorrCfg::Get();
sal_uInt16 nFound = (!rCfg.IsSearchInAllCategories() && pGlossary) ?
pGlossary->GetIndex( aShortName ) : USHRT_MAX;
// if not found then search in all groups
if (nFound == USHRT_MAX)
{
const ::utl::TransliterationWrapper& rSCmp = GetAppCmpStrIgnore();
SwGlossaryList* pGlossaryList = ::GetGlossaryList();
const size_t nGroupCount = pGlossaryList->GetGroupCount();
for(size_t i = 0; i < nGroupCount; ++i)
{
// get group name with path-extension
const OUString sGroupName = pGlossaryList->GetGroupName(i);
if (pGlossary && sGroupName == pGlossary->GetName())
continue;
const sal_uInt16 nBlockCount = pGlossaryList->GetBlockCount(i);
if(nBlockCount)
{
const OUString sTitle = pGlossaryList->GetGroupTitle(i);
for(sal_uInt16 j = 0; j < nBlockCount; j++)
{
const OUString sLongName(pGlossaryList->GetBlockLongName(i, j));
const OUString sShortName(pGlossaryList->GetBlockShortName(i, j));
if( rSCmp.isEqual( rShortName, sShortName ))
{
aFoundArr.emplace_back(sTitle, sLongName, sGroupName);
}
}
}
}
if( !aFoundArr.empty() ) // one was found
{
pGlossary.reset();
if (1 == aFoundArr.size())
{
TextBlockInfo_Impl& rData = aFoundArr.front();
pGlossary = pGlossaries->GetGroupDoc(rData.sGroupName);
nFound = pGlossary->GetIndex( aShortName );
}
else
{
SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
ScopedVclPtr<AbstractSwSelGlossaryDlg> pDlg(pFact->CreateSwSelGlossaryDlg(pParent, aShortName));
for(const TextBlockInfo_Impl & i : aFoundArr)
{
pDlg->InsertGlos(i.sTitle, i.sLongName);
}
pDlg->SelectEntryPos(0);
const sal_Int32 nRet = RET_OK == pDlg->Execute() ?
pDlg->GetSelectedIdx() :
-1;
pDlg.disposeAndClear();
if (nRet != -1)
{
TextBlockInfo_Impl& rData = aFoundArr[nRet];
pGlossary = pGlossaries->GetGroupDoc(rData.sGroupName);
nFound = pGlossary->GetIndex( aShortName );
}
else
{
nFound = USHRT_MAX;
bCancel = true;
}
}
}
}
// not found
if (nFound == USHRT_MAX)
{
if( !bCancel )
{
pGlossary.reset();
const sal_Int32 nMaxLen = 50;
if(m_pWrtShell->IsSelection() && aShortName.getLength() > nMaxLen)
{
aShortName = OUString::Concat(aShortName.subView(0, nMaxLen)) + " ...";
}
OUString aTmp( SwResId(STR_NOGLOS));
aTmp = aTmp.replaceFirst("%1", aShortName);
std::shared_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(m_pWrtShell->GetView().GetFrameWeld(),
VclMessageType::Info, VclButtonsType::Ok,
aTmp));
xInfoBox->runAsync(xInfoBox, [] (sal_uInt32){ });
}
return false;
}
else
{
SvxMacro aStartMacro(OUString(), OUString(), STARBASIC);
SvxMacro aEndMacro(OUString(), OUString(), STARBASIC);
GetMacros( aShortName, aStartMacro, aEndMacro, pGlossary.get() );
// StartAction must not be before HasSelection and DelRight,
// otherwise the possible Shell change gets delayed and
// API-programs would hang.
// Moreover the event macro must also not be called in an action
m_pWrtShell->StartUndo(SwUndoId::INSGLOSSARY);
if( aStartMacro.HasMacro() )
m_pWrtShell->ExecMacro( aStartMacro );
if(m_pWrtShell->HasSelection())
m_pWrtShell->DelLeft();
m_pWrtShell->StartAllAction();
// cache all InputFields
SwInputFieldList aFieldLst( m_pWrtShell, true );
m_pWrtShell->InsertGlossary(*pGlossary, aShortName);
m_pWrtShell->EndAllAction();
if( aEndMacro.HasMacro() )
{
m_pWrtShell->ExecMacro( aEndMacro );
}
m_pWrtShell->EndUndo(SwUndoId::INSGLOSSARY);
// demand input for all new InputFields
if( aFieldLst.BuildSortLst() )
m_pWrtShell->UpdateInputFields( &aFieldLst );
}
return true;
}
// add autotext
bool SwGlossaryHdl::InsertGlossary(const OUString &rName)
{
OSL_ENSURE(m_pWrtShell->CanInsert(), "illegal");
SwTextBlocks *pGlos =
m_pCurGrp ? m_pCurGrp.get() : m_rStatGlossaries.GetGroupDoc(m_aCurGrp).release();
if (!pGlos)
{
if (!m_pCurGrp)
delete pGlos;
return false;
}
SvxMacro aStartMacro(OUString(), OUString(), STARBASIC);
SvxMacro aEndMacro(OUString(), OUString(), STARBASIC);
GetMacros( rName, aStartMacro, aEndMacro, pGlos );
// StartAction must not be before HasSelection and DelRight,
// otherwise the possible Shell change gets delayed and
// API-programs would hang.
// Moreover the event macro must also not be called in an action
if( aStartMacro.HasMacro() )
m_pWrtShell->ExecMacro( aStartMacro );
if( m_pWrtShell->HasSelection() )
m_pWrtShell->DelRight();
m_pWrtShell->StartAllAction();
// cache all InputFields
SwInputFieldList aFieldLst( m_pWrtShell, true );
m_pWrtShell->InsertGlossary(*pGlos, rName);
m_pWrtShell->EndAllAction();
if( aEndMacro.HasMacro() )
{
m_pWrtShell->ExecMacro( aEndMacro );
}
// demand input for all new InputFields
if( aFieldLst.BuildSortLst() )
m_pWrtShell->UpdateInputFields( &aFieldLst );
if(!m_pCurGrp)
delete pGlos;
return true;
}
// set / ask for macro
void SwGlossaryHdl::SetMacros(const OUString& rShortName,
const SvxMacro* pStart,
const SvxMacro* pEnd,
SwTextBlocks *pGlossary )
{
SwTextBlocks *pGlos = pGlossary ? pGlossary :
m_pCurGrp ? m_pCurGrp.get()
: m_rStatGlossaries.GetGroupDoc( m_aCurGrp ).release();
SvxMacroTableDtor aMacroTable;
if( pStart )
aMacroTable.Insert( SvMacroItemId::SwStartInsGlossary, *pStart);
if( pEnd )
aMacroTable.Insert( SvMacroItemId::SwEndInsGlossary, *pEnd);
sal_uInt16 nIdx = pGlos->GetIndex( rShortName );
if( !pGlos->SetMacroTable( nIdx, aMacroTable ) && pGlos->GetError() )
ErrorHandler::HandleError( pGlos->GetError() );
if(!m_pCurGrp && !pGlossary)
delete pGlos;
}
void SwGlossaryHdl::GetMacros( const OUString &rShortName,
SvxMacro& rStart,
SvxMacro& rEnd,
SwTextBlocks *pGlossary )
{
SwTextBlocks *pGlos = pGlossary ? pGlossary
: m_pCurGrp ? m_pCurGrp.get()
: m_rStatGlossaries.GetGroupDoc(m_aCurGrp).release();
sal_uInt16 nIndex = pGlos->GetIndex( rShortName );
if( nIndex != USHRT_MAX )
{
SvxMacroTableDtor aMacroTable;
if( pGlos->GetMacroTable( nIndex, aMacroTable ) )
{
SvxMacro *pMacro = aMacroTable.Get( SvMacroItemId::SwStartInsGlossary );
if( pMacro )
rStart = *pMacro;
pMacro = aMacroTable.Get( SvMacroItemId::SwEndInsGlossary );
if( pMacro )
rEnd = *pMacro;
}
}
if( !m_pCurGrp && !pGlossary )
delete pGlos;
}
// ctor, dtor
SwGlossaryHdl::SwGlossaryHdl(SfxViewFrame& rVwFrame, SwWrtShell *pSh)
: m_rStatGlossaries( *::GetGlossaries() ),
m_aCurGrp( SwGlossaries::GetDefName() ),
m_rViewFrame(rVwFrame),
m_pWrtShell( pSh )
{
}
SwGlossaryHdl::~SwGlossaryHdl()
{
}
// rename an autotext
bool SwGlossaryHdl::Rename(const OUString& rOldShort, const OUString& rNewShortName,
const OUString& rNewName )
{
bool bRet = false;
SwTextBlocks *pGlossary = m_pCurGrp ? m_pCurGrp.get()
: m_rStatGlossaries.GetGroupDoc(m_aCurGrp).release();
if(pGlossary)
{
sal_uInt16 nIdx = pGlossary->GetIndex( rOldShort );
sal_uInt16 nOldLongIdx = pGlossary->GetLongIndex( rNewName );
sal_uInt16 nOldIdx = pGlossary->GetIndex( rNewShortName );
if( nIdx != USHRT_MAX &&
(nOldLongIdx == USHRT_MAX || nOldLongIdx == nIdx )&&
(nOldIdx == USHRT_MAX || nOldIdx == nIdx ))
{
pGlossary->Rename( nIdx, &rNewShortName, &rNewName );
bRet = pGlossary->GetError() == ERRCODE_NONE;
}
if( !m_pCurGrp )
delete pGlossary;
}
return bRet;
}
bool SwGlossaryHdl::IsReadOnly( const OUString* pGrpNm ) const
{
SwTextBlocks *pGlossary = nullptr;
if (pGrpNm)
pGlossary = m_rStatGlossaries.GetGroupDoc( *pGrpNm ).release();
else if (m_pCurGrp)
pGlossary = m_pCurGrp.get();
else
pGlossary = m_rStatGlossaries.GetGroupDoc(m_aCurGrp).release();
const bool bRet = !pGlossary || pGlossary->IsReadOnly();
if( pGrpNm || !m_pCurGrp )
delete pGlossary;
return bRet;
}
bool SwGlossaryHdl::IsOld() const
{
if( !m_pCurGrp )
m_rStatGlossaries.GetGroupDoc(m_aCurGrp).reset();
return false;
}
// find group without path index
bool SwGlossaryHdl::FindGroupName(OUString& rGroup)
{
return m_rStatGlossaries.FindGroupName(rGroup);
}
bool SwGlossaryHdl::CopyToClipboard(SwWrtShell& rSh, const OUString& rShortName)
{
SwTextBlocks *pGlossary = m_pCurGrp ? m_pCurGrp.get()
: m_rStatGlossaries.GetGroupDoc(m_aCurGrp).release();
rtl::Reference<SwTransferable> pTransfer = new SwTransferable( rSh );
bool bRet = pTransfer->CopyGlossary( *pGlossary, rShortName );
if( !m_pCurGrp )
delete pGlossary;
return bRet;
}
bool SwGlossaryHdl::ImportGlossaries( const OUString& rName )
{
bool bRet = false;
if( !rName.isEmpty() )
{
std::shared_ptr<const SfxFilter> pFilter;
SfxMedium aMed( rName, StreamMode::READ, nullptr, nullptr );
SfxFilterMatcher aMatcher( u"swriter"_ustr );
aMed.UseInteractionHandler( true );
if (aMatcher.GuessFilter(aMed, pFilter, SfxFilterFlags::NONE) == ERRCODE_NONE)
{
assert(pFilter && "success means pFilter was set");
SwTextBlocks *pGlossary = nullptr;
aMed.SetFilter( pFilter );
Reader* pR = SwReaderWriter::GetReader( pFilter->GetUserData() );
if( pR && nullptr != ( pGlossary = m_pCurGrp ? m_pCurGrp.get()
: m_rStatGlossaries.GetGroupDoc(m_aCurGrp).release()) )
{
SwReader aReader( aMed, rName );
if( aReader.HasGlossaries( *pR ) )
{
const SvxAutoCorrCfg& rCfg = SvxAutoCorrCfg::Get();
bRet = aReader.ReadGlossaries( *pR, *pGlossary,
rCfg.IsSaveRelFile() );
}
if (!m_pCurGrp)
delete pGlossary;
}
}
}
return bRet;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
↑ V575 The null pointer is passed into 'operator delete'. Inspect the argument.
↑ V575 The null pointer is passed into 'operator delete'. Inspect the argument.
↑ V575 The null pointer is passed into 'operator delete'. Inspect the argument.