1931 lines
66 KiB
C++
1931 lines
66 KiB
C++
/* -*- 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 <config_features.h>
|
|
#include <config_fuzzers.h>
|
|
|
|
#include <cmdid.h>
|
|
#include <hintids.hxx>
|
|
#include <svl/numformat.hxx>
|
|
#include <svl/stritem.hxx>
|
|
#include <com/sun/star/text/DefaultNumberingProvider.hpp>
|
|
#include <com/sun/star/text/XDefaultNumberingProvider.hpp>
|
|
#include <com/sun/star/text/XNumberingTypeInfo.hpp>
|
|
#include <com/sun/star/style/NumberingType.hpp>
|
|
#include <com/sun/star/beans/XPropertySet.hpp>
|
|
#include <com/sun/star/sdbc/XConnection.hpp>
|
|
#include <com/sun/star/sdbc/XDataSource.hpp>
|
|
#include <com/sun/star/uri/UriReferenceFactory.hpp>
|
|
#include <com/sun/star/uri/XVndSunStarScriptUrl.hpp>
|
|
#include <comphelper/processfactory.hxx>
|
|
#include <comphelper/string.hxx>
|
|
#include <o3tl/string_view.hxx>
|
|
#include <tools/resary.hxx>
|
|
#include <osl/diagnose.h>
|
|
#include <sfx2/dispatch.hxx>
|
|
#include <sfx2/linkmgr.hxx>
|
|
#include <sfx2/app.hxx>
|
|
#include <sfx2/viewfrm.hxx>
|
|
#include <svx/strarray.hxx>
|
|
#include <fmtrfmrk.hxx>
|
|
#include <svl/zforlist.hxx>
|
|
#include <svl/zformat.hxx>
|
|
#include <vcl/mnemonic.hxx>
|
|
#include <view.hxx>
|
|
#include <wrtsh.hxx>
|
|
#include <doc.hxx>
|
|
#include <swmodule.hxx>
|
|
#include <fmtinfmt.hxx>
|
|
#include <cellatr.hxx>
|
|
#include <dbmgr.hxx>
|
|
#include <shellres.hxx>
|
|
#include <fldbas.hxx>
|
|
#include <docufld.hxx>
|
|
#include <chpfld.hxx>
|
|
#include <ddefld.hxx>
|
|
#include <expfld.hxx>
|
|
#include <reffld.hxx>
|
|
#include <usrfld.hxx>
|
|
#include <dbfld.hxx>
|
|
#include <authfld.hxx>
|
|
#include <flddat.hxx>
|
|
#include <fldmgr.hxx>
|
|
#include <ndtxt.hxx>
|
|
#include <cntfrm.hxx>
|
|
#include <flddropdown.hxx>
|
|
#include <strings.hrc>
|
|
#include <tox.hxx>
|
|
#include <viewopt.hxx>
|
|
#include <txmsrt.hxx>
|
|
#include <unotools/useroptions.hxx>
|
|
#include <IDocumentContentOperations.hxx>
|
|
#include <translatehelper.hxx>
|
|
|
|
using namespace com::sun::star::uno;
|
|
using namespace com::sun::star::container;
|
|
using namespace com::sun::star::beans;
|
|
using namespace com::sun::star::text;
|
|
using namespace com::sun::star::style;
|
|
using namespace com::sun::star::sdbc;
|
|
using namespace ::com::sun::star;
|
|
using namespace nsSwDocInfoSubType;
|
|
|
|
// groups of fields
|
|
enum
|
|
{
|
|
GRP_DOC_BEGIN = 0,
|
|
GRP_DOC_END = GRP_DOC_BEGIN + 12,
|
|
|
|
GRP_FKT_BEGIN = GRP_DOC_END,
|
|
GRP_FKT_END = GRP_FKT_BEGIN + 8,
|
|
|
|
GRP_REF_BEGIN = GRP_FKT_END,
|
|
GRP_REF_END = GRP_REF_BEGIN + 2,
|
|
|
|
GRP_REG_BEGIN = GRP_REF_END,
|
|
GRP_REG_END = GRP_REG_BEGIN + 1,
|
|
|
|
GRP_DB_BEGIN = GRP_REG_END,
|
|
GRP_DB_END = GRP_DB_BEGIN + 5,
|
|
|
|
GRP_VAR_BEGIN = GRP_DB_END,
|
|
GRP_VAR_END = GRP_VAR_BEGIN + 9
|
|
};
|
|
|
|
enum
|
|
{
|
|
GRP_WEB_DOC_BEGIN = 0,
|
|
GRP_WEB_DOC_END = GRP_WEB_DOC_BEGIN + 9,
|
|
|
|
GRP_WEB_FKT_BEGIN = GRP_WEB_DOC_END + 2,
|
|
GRP_WEB_FKT_END = GRP_WEB_FKT_BEGIN + 0, // the group is empty!
|
|
|
|
GRP_WEB_REF_BEGIN = GRP_WEB_FKT_END + 6, // the group is empty!
|
|
GRP_WEB_REF_END = GRP_WEB_REF_BEGIN + 0,
|
|
|
|
GRP_WEB_REG_BEGIN = GRP_WEB_REF_END + 2,
|
|
GRP_WEB_REG_END = GRP_WEB_REG_BEGIN + 1,
|
|
|
|
GRP_WEB_DB_BEGIN = GRP_WEB_REG_END, // the group is empty!
|
|
GRP_WEB_DB_END = GRP_WEB_DB_BEGIN + 0,
|
|
|
|
GRP_WEB_VAR_BEGIN = GRP_WEB_DB_END + 5,
|
|
GRP_WEB_VAR_END = GRP_WEB_VAR_BEGIN + 1
|
|
};
|
|
|
|
const sal_uInt16 VF_COUNT = 1; // { 0 }
|
|
const sal_uInt16 VF_USR_COUNT = 2; // { 0, nsSwExtendedSubType::SUB_CMD }
|
|
const sal_uInt16 VF_DB_COUNT = 1; // { nsSwExtendedSubType::SUB_OWN_FMT }
|
|
|
|
const TranslateId FLD_EU_ARY[] =
|
|
{
|
|
FLD_EU_COMPANY,
|
|
FLD_EU_GIVENNAME,
|
|
FLD_EU_SURNAME,
|
|
FLD_EU_INITIALS,
|
|
FLD_EU_STREET,
|
|
FLD_EU_COUNTRY,
|
|
FLD_EU_POSTCODE,
|
|
FLD_EU_TOWN,
|
|
FLD_EU_TITLE,
|
|
FLD_EU_POS,
|
|
FLD_EU_TELPERSONAL,
|
|
FLD_EU_TELWORK,
|
|
FLD_EU_FAX,
|
|
FLD_EU_EMAIL,
|
|
FLD_EU_REGION
|
|
};
|
|
|
|
const TranslateId FMT_AUTHOR_ARY[] =
|
|
{
|
|
FMT_AUTHOR_NAME,
|
|
FMT_AUTHOR_SCUT
|
|
};
|
|
|
|
const TranslateId FLD_DATE_ARY[] =
|
|
{
|
|
FLD_DATE_FIX,
|
|
FLD_DATE_STD,
|
|
};
|
|
|
|
const TranslateId FLD_TIME_ARY[] =
|
|
{
|
|
FLD_TIME_FIX,
|
|
FLD_TIME_STD
|
|
};
|
|
|
|
const TranslateId FMT_NUM_ARY[] =
|
|
{
|
|
FMT_NUM_ABC,
|
|
FMT_NUM_SABC,
|
|
FMT_NUM_ABC_N,
|
|
FMT_NUM_SABC_N,
|
|
FMT_NUM_ROMAN,
|
|
FMT_NUM_SROMAN,
|
|
FMT_NUM_ARABIC,
|
|
FMT_NUM_PAGEDESC,
|
|
FMT_NUM_PAGESPECIAL
|
|
};
|
|
|
|
const TranslateId FMT_FF_ARY[] =
|
|
{
|
|
FMT_FF_NAME,
|
|
FMT_FF_PATHNAME,
|
|
FMT_FF_PATH,
|
|
FMT_FF_NAME_NOEXT,
|
|
FMT_FF_UI_NAME,
|
|
FMT_FF_UI_RANGE
|
|
};
|
|
|
|
const TranslateId FLD_STAT_ARY[] =
|
|
{
|
|
FLD_STAT_PAGE,
|
|
FLD_STAT_PARA,
|
|
FLD_STAT_WORD,
|
|
FLD_STAT_CHAR,
|
|
FLD_STAT_TABLE,
|
|
FLD_STAT_GRF,
|
|
FLD_STAT_OBJ
|
|
};
|
|
|
|
const TranslateId FMT_CHAPTER_ARY[] =
|
|
{
|
|
FMT_CHAPTER_NO,
|
|
FMT_CHAPTER_NAME,
|
|
FMT_CHAPTER_NAMENO,
|
|
FMT_CHAPTER_NO_NOSEPARATOR
|
|
};
|
|
|
|
const TranslateId FLD_INPUT_ARY[] =
|
|
{
|
|
FLD_INPUT_TEXT
|
|
};
|
|
|
|
const TranslateId FMT_MARK_ARY[] =
|
|
{
|
|
FMT_MARK_TEXT,
|
|
FMT_MARK_TABLE,
|
|
FMT_MARK_FRAME,
|
|
FMT_MARK_GRAFIC,
|
|
FMT_MARK_OLE
|
|
};
|
|
|
|
const TranslateId FMT_REF_ARY[] =
|
|
{
|
|
FMT_REF_PAGE,
|
|
FMT_REF_CHAPTER,
|
|
FMT_REF_TEXT,
|
|
FMT_REF_UPDOWN,
|
|
FMT_REF_PAGE_PGDSC,
|
|
FMT_REF_ONLYNUMBER,
|
|
FMT_REF_ONLYCAPTION,
|
|
FMT_REF_ONLYSEQNO,
|
|
FMT_REF_NUMBER,
|
|
FMT_REF_NUMBER_NO_CONTEXT,
|
|
FMT_REF_NUMBER_FULL_CONTEXT
|
|
};
|
|
|
|
const TranslateId FMT_REG_ARY[] =
|
|
{
|
|
FMT_REG_AUTHOR,
|
|
FMT_REG_TIME,
|
|
FMT_REG_DATE
|
|
};
|
|
|
|
const TranslateId FMT_DBFLD_ARY[] =
|
|
{
|
|
FMT_DBFLD_DB,
|
|
FMT_DBFLD_SYS
|
|
};
|
|
|
|
const TranslateId FMT_SETVAR_ARY[] =
|
|
{
|
|
FMT_SETVAR_SYS,
|
|
FMT_SETVAR_TEXT
|
|
};
|
|
|
|
const TranslateId FMT_GETVAR_ARY[] =
|
|
{
|
|
FMT_GETVAR_TEXT,
|
|
FMT_GETVAR_NAME
|
|
};
|
|
|
|
const TranslateId FMT_DDE_ARY[] =
|
|
{
|
|
FMT_DDE_NORMAL,
|
|
FMT_DDE_HOT
|
|
};
|
|
|
|
const TranslateId FLD_PAGEREF_ARY[] =
|
|
{
|
|
FLD_PAGEREF_OFF,
|
|
FLD_PAGEREF_ON
|
|
};
|
|
|
|
const TranslateId FMT_USERVAR_ARY[] =
|
|
{
|
|
FMT_USERVAR_TEXT,
|
|
FMT_USERVAR_CMD
|
|
};
|
|
|
|
namespace {
|
|
|
|
// field types and subtypes
|
|
struct SwFieldPack
|
|
{
|
|
SwFieldTypesEnum nTypeId;
|
|
|
|
const TranslateId* pSubTypeResIds;
|
|
size_t nSubTypeLength;
|
|
|
|
const TranslateId* pFormatResIds;
|
|
size_t nFormatLength;
|
|
};
|
|
|
|
}
|
|
|
|
// strings and formats
|
|
const SwFieldPack aSwFields[] =
|
|
{
|
|
// Document
|
|
{ SwFieldTypesEnum::ExtendedUser, FLD_EU_ARY, std::size(FLD_EU_ARY), nullptr, 0 },
|
|
{ SwFieldTypesEnum::Author, nullptr, 0, FMT_AUTHOR_ARY, std::size(FMT_AUTHOR_ARY) },
|
|
{ SwFieldTypesEnum::Date, FLD_DATE_ARY, std::size(FLD_DATE_ARY), nullptr, 0 },
|
|
{ SwFieldTypesEnum::Time, FLD_TIME_ARY, std::size(FLD_TIME_ARY), nullptr, 0 },
|
|
{ SwFieldTypesEnum::PageNumber, nullptr, 0, FMT_NUM_ARY, std::size(FMT_NUM_ARY) -1 },
|
|
{ SwFieldTypesEnum::NextPage, nullptr, 0, FMT_NUM_ARY, std::size(FMT_NUM_ARY) },
|
|
{ SwFieldTypesEnum::PreviousPage, nullptr, 0, FMT_NUM_ARY, std::size(FMT_NUM_ARY) },
|
|
{ SwFieldTypesEnum::Filename, nullptr, 0, FMT_FF_ARY, std::size(FMT_FF_ARY) },
|
|
{ SwFieldTypesEnum::DocumentStatistics, FLD_STAT_ARY, std::size(FLD_STAT_ARY), FMT_NUM_ARY, std::size(FMT_NUM_ARY) -1 },
|
|
|
|
{ SwFieldTypesEnum::Chapter, nullptr, 0, FMT_CHAPTER_ARY, std::size(FMT_CHAPTER_ARY) },
|
|
{ SwFieldTypesEnum::TemplateName, nullptr, 0, FMT_FF_ARY, std::size(FMT_FF_ARY) },
|
|
{ SwFieldTypesEnum::ParagraphSignature, nullptr, 0, nullptr, 0 },
|
|
|
|
// Functions
|
|
{ SwFieldTypesEnum::ConditionalText, nullptr, 0, nullptr, 0 },
|
|
{ SwFieldTypesEnum::Dropdown, nullptr, 0, nullptr, 0 },
|
|
{ SwFieldTypesEnum::Input, FLD_INPUT_ARY, std::size(FLD_INPUT_ARY), nullptr, 0 },
|
|
{ SwFieldTypesEnum::Macro, nullptr, 0, nullptr, 0 },
|
|
{ SwFieldTypesEnum::JumpEdit, nullptr, 0, FMT_MARK_ARY, std::size(FMT_MARK_ARY) },
|
|
{ SwFieldTypesEnum::CombinedChars, nullptr, 0, nullptr, 0 },
|
|
{ SwFieldTypesEnum::HiddenText, nullptr, 0, nullptr, 0 },
|
|
{ SwFieldTypesEnum::HiddenParagraph, nullptr, 0, nullptr, 0 },
|
|
|
|
// Cross-References
|
|
{ SwFieldTypesEnum::SetRef, nullptr, 0, nullptr, 0 },
|
|
{ SwFieldTypesEnum::GetRef, nullptr, 0, FMT_REF_ARY, std::size(FMT_REF_ARY) },
|
|
|
|
// DocInformation
|
|
{ SwFieldTypesEnum::DocumentInfo, nullptr, 0, FMT_REG_ARY, std::size(FMT_REG_ARY) },
|
|
|
|
// Database
|
|
{ SwFieldTypesEnum::Database, nullptr, 0, FMT_DBFLD_ARY, std::size(FMT_DBFLD_ARY) },
|
|
{ SwFieldTypesEnum::DatabaseNextSet, nullptr, 0, nullptr, 0 },
|
|
{ SwFieldTypesEnum::DatabaseNumberSet, nullptr, 0, nullptr, 0 },
|
|
{ SwFieldTypesEnum::DatabaseSetNumber, nullptr, 0, FMT_NUM_ARY, std::size(FMT_NUM_ARY) - 2 },
|
|
{ SwFieldTypesEnum::DatabaseName, nullptr, 0, nullptr, 0 },
|
|
|
|
// Variables
|
|
{ SwFieldTypesEnum::Set, nullptr, 0, FMT_SETVAR_ARY, std::size(FMT_SETVAR_ARY) },
|
|
|
|
{ SwFieldTypesEnum::Get, nullptr, 0, FMT_GETVAR_ARY, std::size(FMT_GETVAR_ARY) },
|
|
{ SwFieldTypesEnum::DDE, nullptr, 0, FMT_DDE_ARY, std::size(FMT_DDE_ARY) },
|
|
{ SwFieldTypesEnum::Formel, nullptr, 0, FMT_GETVAR_ARY, std::size(FMT_GETVAR_ARY) },
|
|
{ SwFieldTypesEnum::Input, FLD_INPUT_ARY, std::size(FLD_INPUT_ARY), nullptr, 0 },
|
|
{ SwFieldTypesEnum::Sequence, nullptr, 0, FMT_NUM_ARY, std::size(FMT_NUM_ARY) - 2 },
|
|
{ SwFieldTypesEnum::SetRefPage, FLD_PAGEREF_ARY, std::size(FLD_PAGEREF_ARY),nullptr, 0 },
|
|
{ SwFieldTypesEnum::GetRefPage, nullptr, 0, FMT_NUM_ARY, std::size(FMT_NUM_ARY) - 1 },
|
|
{ SwFieldTypesEnum::User, nullptr, 0, FMT_USERVAR_ARY, std::size(FMT_USERVAR_ARY) }
|
|
};
|
|
|
|
// access to the shell
|
|
static SwWrtShell* lcl_GetShell()
|
|
{
|
|
if (SwView* pView = GetActiveView())
|
|
return pView->GetWrtShellPtr();
|
|
return nullptr;
|
|
}
|
|
|
|
static sal_uInt16 GetPackCount() { return SAL_N_ELEMENTS(aSwFields); }
|
|
|
|
// FieldManager controls inserting and updating of fields
|
|
SwFieldMgr::SwFieldMgr(SwWrtShell* pSh ) :
|
|
m_pWrtShell(pSh),
|
|
m_bEvalExp(true)
|
|
{
|
|
// determine current field if existing
|
|
GetCurField();
|
|
}
|
|
|
|
SwFieldMgr::~SwFieldMgr()
|
|
{
|
|
}
|
|
|
|
// organise RefMark by names
|
|
bool SwFieldMgr::CanInsertRefMark( std::u16string_view rStr )
|
|
{
|
|
bool bRet = false;
|
|
SwWrtShell *pSh = m_pWrtShell ? m_pWrtShell : lcl_GetShell();
|
|
OSL_ENSURE(pSh, "no SwWrtShell found");
|
|
if(pSh)
|
|
{
|
|
sal_uInt16 nCnt = pSh->GetCursorCnt();
|
|
|
|
// the last Cursor doesn't have to be a spanned selection
|
|
if( 1 < nCnt && !pSh->SwCursorShell::HasSelection() )
|
|
--nCnt;
|
|
|
|
bRet = 2 > nCnt && nullptr == pSh->GetRefMark( rStr );
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
// access over ResIds
|
|
void SwFieldMgr::RemoveFieldType(SwFieldIds nResId, const OUString& rName )
|
|
{
|
|
SwWrtShell * pSh = m_pWrtShell ? m_pWrtShell : lcl_GetShell();
|
|
OSL_ENSURE(pSh, "no SwWrtShell found");
|
|
if( pSh )
|
|
pSh->RemoveFieldType(nResId, rName);
|
|
}
|
|
|
|
size_t SwFieldMgr::GetFieldTypeCount() const
|
|
{
|
|
SwWrtShell * pSh = m_pWrtShell ? m_pWrtShell : lcl_GetShell();
|
|
OSL_ENSURE(pSh, "no SwWrtShell found");
|
|
return pSh ? pSh->GetFieldTypeCount() : 0;
|
|
}
|
|
|
|
SwFieldType* SwFieldMgr::GetFieldType(SwFieldIds nResId, size_t nField) const
|
|
{
|
|
SwWrtShell * pSh = m_pWrtShell ? m_pWrtShell : lcl_GetShell();
|
|
OSL_ENSURE(pSh, "no SwWrtShell found");
|
|
return pSh ? pSh->GetFieldType(nField, nResId) : nullptr;
|
|
}
|
|
|
|
SwFieldType* SwFieldMgr::GetFieldType(SwFieldIds nResId, const OUString& rName) const
|
|
{
|
|
SwWrtShell * pSh = m_pWrtShell ? m_pWrtShell : lcl_GetShell();
|
|
OSL_ENSURE(pSh, "no SwWrtShell found");
|
|
return pSh ? pSh->GetFieldType(nResId, rName) : nullptr;
|
|
}
|
|
|
|
// determine current field
|
|
SwField* SwFieldMgr::GetCurField()
|
|
{
|
|
SwWrtShell *pSh = m_pWrtShell ? m_pWrtShell : ::lcl_GetShell();
|
|
if ( pSh )
|
|
m_pCurField = pSh->GetCurField( true );
|
|
else
|
|
m_pCurField = nullptr;
|
|
|
|
// initialise strings and format
|
|
m_aCurPar1.clear();
|
|
m_aCurPar2.clear();
|
|
m_sCurFrame.clear();
|
|
|
|
if(!m_pCurField)
|
|
return nullptr;
|
|
|
|
// preprocess current values; determine parameter 1 and parameter 2
|
|
|
|
m_aCurPar1 = m_pCurField->GetPar1();
|
|
m_aCurPar2 = m_pCurField->GetPar2();
|
|
|
|
return m_pCurField;
|
|
}
|
|
|
|
// provide group range
|
|
const SwFieldGroupRgn& SwFieldMgr::GetGroupRange(bool bHtmlMode, sal_uInt16 nGrpId)
|
|
{
|
|
static SwFieldGroupRgn const aRanges[] =
|
|
{
|
|
{ /* Document */ GRP_DOC_BEGIN, GRP_DOC_END },
|
|
{ /* Functions */ GRP_FKT_BEGIN, GRP_FKT_END },
|
|
{ /* Cross-Refs */ GRP_REF_BEGIN, GRP_REF_END },
|
|
{ /* DocInfos */ GRP_REG_BEGIN, GRP_REG_END },
|
|
{ /* Database */ GRP_DB_BEGIN, GRP_DB_END },
|
|
{ /* User */ GRP_VAR_BEGIN, GRP_VAR_END }
|
|
};
|
|
static SwFieldGroupRgn const aWebRanges[] =
|
|
{
|
|
{ /* Document */ GRP_WEB_DOC_BEGIN, GRP_WEB_DOC_END },
|
|
{ /* Functions */ GRP_WEB_FKT_BEGIN, GRP_WEB_FKT_END },
|
|
{ /* Cross-Refs */ GRP_WEB_REF_BEGIN, GRP_WEB_REF_END },
|
|
{ /* DocInfos */ GRP_WEB_REG_BEGIN, GRP_WEB_REG_END },
|
|
{ /* Database */ GRP_WEB_DB_BEGIN, GRP_WEB_DB_END },
|
|
{ /* User */ GRP_WEB_VAR_BEGIN, GRP_WEB_VAR_END }
|
|
};
|
|
|
|
if (bHtmlMode)
|
|
return aWebRanges[nGrpId];
|
|
else
|
|
return aRanges[nGrpId];
|
|
}
|
|
|
|
// determine GroupId
|
|
sal_uInt16 SwFieldMgr::GetGroup(SwFieldTypesEnum nTypeId, sal_uInt16 nSubType)
|
|
{
|
|
if (nTypeId == SwFieldTypesEnum::SetInput)
|
|
nTypeId = SwFieldTypesEnum::Set;
|
|
|
|
if (nTypeId == SwFieldTypesEnum::Input && (nSubType & INP_USR))
|
|
nTypeId = SwFieldTypesEnum::User;
|
|
|
|
if (nTypeId == SwFieldTypesEnum::FixedDate)
|
|
nTypeId = SwFieldTypesEnum::Date;
|
|
|
|
if (nTypeId == SwFieldTypesEnum::FixedTime)
|
|
nTypeId = SwFieldTypesEnum::Time;
|
|
|
|
for (sal_uInt16 i = GRP_DOC; i <= GRP_VAR; i++)
|
|
{
|
|
const SwFieldGroupRgn& rRange = GetGroupRange(false/*bHtmlMode*/, i);
|
|
for (sal_uInt16 nPos = rRange.nStart; nPos < rRange.nEnd; nPos++)
|
|
{
|
|
if (aSwFields[nPos].nTypeId == nTypeId)
|
|
return i;
|
|
}
|
|
}
|
|
return USHRT_MAX;
|
|
}
|
|
|
|
// determine names to TypeId
|
|
// ACCESS over TYP_...
|
|
SwFieldTypesEnum SwFieldMgr::GetTypeId(sal_uInt16 nPos)
|
|
{
|
|
OSL_ENSURE(nPos < ::GetPackCount(), "forbidden Pos");
|
|
return aSwFields[ nPos ].nTypeId;
|
|
}
|
|
|
|
const OUString & SwFieldMgr::GetTypeStr(sal_uInt16 nPos)
|
|
{
|
|
OSL_ENSURE(nPos < ::GetPackCount(), "forbidden TypeId");
|
|
|
|
SwFieldTypesEnum nFieldWh = aSwFields[ nPos ].nTypeId;
|
|
|
|
// special treatment for date/time fields (without var/fix)
|
|
if( SwFieldTypesEnum::Date == nFieldWh )
|
|
{
|
|
static OUString g_aDate( SwResId( STR_DATEFLD ) );
|
|
return g_aDate;
|
|
}
|
|
if( SwFieldTypesEnum::Time == nFieldWh )
|
|
{
|
|
static OUString g_aTime( SwResId( STR_TIMEFLD ) );
|
|
return g_aTime;
|
|
}
|
|
|
|
return SwFieldType::GetTypeStr( nFieldWh );
|
|
}
|
|
|
|
// determine Pos in the list
|
|
sal_uInt16 SwFieldMgr::GetPos(SwFieldTypesEnum nTypeId)
|
|
{
|
|
switch( nTypeId )
|
|
{
|
|
case SwFieldTypesEnum::FixedDate: nTypeId = SwFieldTypesEnum::Date; break;
|
|
case SwFieldTypesEnum::FixedTime: nTypeId = SwFieldTypesEnum::Time; break;
|
|
case SwFieldTypesEnum::SetInput: nTypeId = SwFieldTypesEnum::Set; break;
|
|
case SwFieldTypesEnum::UserInput: nTypeId = SwFieldTypesEnum::User; break;
|
|
default: break;
|
|
}
|
|
|
|
for(sal_uInt16 i = 0; i < GetPackCount(); i++)
|
|
if(aSwFields[i].nTypeId == nTypeId)
|
|
return i;
|
|
|
|
return USHRT_MAX;
|
|
}
|
|
|
|
// localise subtypes of a field
|
|
void SwFieldMgr::GetSubTypes(SwFieldTypesEnum nTypeId, std::vector<OUString>& rToFill)
|
|
{
|
|
SwWrtShell *pSh = m_pWrtShell ? m_pWrtShell : lcl_GetShell();
|
|
OSL_ENSURE(pSh, "no SwWrtShell found");
|
|
if(!pSh)
|
|
return;
|
|
|
|
const sal_uInt16 nPos = GetPos(nTypeId);
|
|
|
|
switch(nTypeId)
|
|
{
|
|
case SwFieldTypesEnum::SetRef:
|
|
case SwFieldTypesEnum::GetRef:
|
|
{
|
|
// references are no fields
|
|
pSh->GetRefMarks( &rToFill );
|
|
break;
|
|
}
|
|
case SwFieldTypesEnum::Macro:
|
|
{
|
|
break;
|
|
}
|
|
case SwFieldTypesEnum::Input:
|
|
{
|
|
rToFill.push_back(SwResId(aSwFields[nPos].pSubTypeResIds[0]));
|
|
[[fallthrough]]; // move on at generic types
|
|
}
|
|
case SwFieldTypesEnum::DDE:
|
|
case SwFieldTypesEnum::Sequence:
|
|
case SwFieldTypesEnum::Formel:
|
|
case SwFieldTypesEnum::Get:
|
|
case SwFieldTypesEnum::Set:
|
|
case SwFieldTypesEnum::User:
|
|
{
|
|
|
|
const size_t nCount = pSh->GetFieldTypeCount();
|
|
for(size_t i = 0; i < nCount; ++i)
|
|
{
|
|
SwFieldType* pFieldType = pSh->GetFieldType( i );
|
|
const SwFieldIds nWhich = pFieldType->Which();
|
|
|
|
if((nTypeId == SwFieldTypesEnum::DDE && pFieldType->Which() == SwFieldIds::Dde) ||
|
|
|
|
(nTypeId == SwFieldTypesEnum::User && nWhich == SwFieldIds::User) ||
|
|
|
|
(nTypeId == SwFieldTypesEnum::Get && nWhich == SwFieldIds::SetExp &&
|
|
!(static_cast<SwSetExpFieldType*>(pFieldType)->GetType() & nsSwGetSetExpType::GSE_SEQ)) ||
|
|
|
|
(nTypeId == SwFieldTypesEnum::Set && nWhich == SwFieldIds::SetExp &&
|
|
!(static_cast<SwSetExpFieldType*>(pFieldType)->GetType() & nsSwGetSetExpType::GSE_SEQ)) ||
|
|
|
|
(nTypeId == SwFieldTypesEnum::Sequence && nWhich == SwFieldIds::SetExp &&
|
|
(static_cast<SwSetExpFieldType*>(pFieldType)->GetType() & nsSwGetSetExpType::GSE_SEQ)) ||
|
|
|
|
((nTypeId == SwFieldTypesEnum::Input || nTypeId == SwFieldTypesEnum::Formel) &&
|
|
(nWhich == SwFieldIds::User ||
|
|
(nWhich == SwFieldIds::SetExp &&
|
|
!(static_cast<SwSetExpFieldType*>(pFieldType)->GetType() & nsSwGetSetExpType::GSE_SEQ))) ) )
|
|
{
|
|
rToFill.push_back(pFieldType->GetName());
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case SwFieldTypesEnum::DatabaseNextSet:
|
|
case SwFieldTypesEnum::DatabaseNumberSet:
|
|
case SwFieldTypesEnum::DatabaseName:
|
|
case SwFieldTypesEnum::DatabaseSetNumber:
|
|
break;
|
|
|
|
default:
|
|
{
|
|
// static SubTypes
|
|
if(nPos != USHRT_MAX)
|
|
{
|
|
sal_uInt16 nCount;
|
|
if (nTypeId == SwFieldTypesEnum::DocumentInfo)
|
|
nCount = DI_SUBTYPE_END - DI_SUBTYPE_BEGIN;
|
|
else
|
|
nCount = aSwFields[nPos].nSubTypeLength;
|
|
|
|
for(sal_uInt16 i = 0; i < nCount; ++i)
|
|
{
|
|
OUString sNew;
|
|
if (nTypeId == SwFieldTypesEnum::DocumentInfo)
|
|
{
|
|
if ( i == DI_CUSTOM )
|
|
sNew = SwResId(STR_CUSTOM_FIELD);
|
|
else
|
|
sNew = SwViewShell::GetShellRes()->aDocInfoLst[i];
|
|
}
|
|
else
|
|
sNew = SwResId(aSwFields[nPos].pSubTypeResIds[i]);
|
|
|
|
rToFill.push_back(sNew);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// determine format
|
|
// ACCESS over TYP_...
|
|
sal_uInt16 SwFieldMgr::GetFormatCount(SwFieldTypesEnum nTypeId, bool bHtmlMode) const
|
|
{
|
|
assert(nTypeId < SwFieldTypesEnum::LAST && "forbidden TypeId");
|
|
{
|
|
const sal_uInt16 nPos = GetPos(nTypeId);
|
|
|
|
if (nPos == USHRT_MAX || (bHtmlMode && nTypeId == SwFieldTypesEnum::Set))
|
|
return 0;
|
|
|
|
sal_uInt16 nCount = aSwFields[nPos].nFormatLength;
|
|
|
|
if (nTypeId == SwFieldTypesEnum::Filename)
|
|
nCount -= 2; // no range or template
|
|
|
|
const TranslateId* pStart = aSwFields[nPos].pFormatResIds;
|
|
if (!pStart)
|
|
return nCount;
|
|
|
|
if (*pStart == FMT_GETVAR_ARY[0] || *pStart == FMT_SETVAR_ARY[0])
|
|
return VF_COUNT;
|
|
else if (*pStart == FMT_USERVAR_ARY[0])
|
|
return VF_USR_COUNT;
|
|
else if (*pStart == FMT_DBFLD_ARY[0])
|
|
return VF_DB_COUNT;
|
|
else if (*pStart == FMT_NUM_ARY[0])
|
|
{
|
|
GetNumberingInfo();
|
|
if(m_xNumberingInfo.is())
|
|
{
|
|
const Sequence<sal_Int16> aTypes = m_xNumberingInfo->getSupportedNumberingTypes();
|
|
// #i28073# it's not necessarily a sorted sequence
|
|
//skip all values below or equal to CHARS_LOWER_LETTER_N
|
|
nCount += std::count_if(aTypes.begin(), aTypes.end(),
|
|
[](sal_Int16 nCurrent) { return nCurrent > NumberingType::CHARS_LOWER_LETTER_N; });
|
|
}
|
|
return nCount;
|
|
}
|
|
|
|
return nCount;
|
|
}
|
|
}
|
|
|
|
// determine FormatString to a type
|
|
OUString SwFieldMgr::GetFormatStr(SwFieldTypesEnum nTypeId, sal_uInt32 nFormatId) const
|
|
{
|
|
assert(nTypeId < SwFieldTypesEnum::LAST && "forbidden TypeId");
|
|
const sal_uInt16 nPos = GetPos(nTypeId);
|
|
|
|
if (nPos == USHRT_MAX)
|
|
return OUString();
|
|
|
|
const TranslateId* pStart = aSwFields[nPos].pFormatResIds;
|
|
if (!pStart)
|
|
return OUString();
|
|
|
|
if (SwFieldTypesEnum::Author == nTypeId || SwFieldTypesEnum::Filename == nTypeId)
|
|
nFormatId &= ~static_cast<sal_uInt32>(FF_FIXED); // mask out Fixed-Flag
|
|
|
|
if (nFormatId < aSwFields[nPos].nFormatLength)
|
|
return SwResId(pStart[nFormatId]);
|
|
|
|
OUString aRet;
|
|
if (*pStart == FMT_NUM_ARY[0])
|
|
{
|
|
if (m_xNumberingInfo.is())
|
|
{
|
|
const Sequence<sal_Int16> aTypes = m_xNumberingInfo->getSupportedNumberingTypes();
|
|
sal_Int32 nOffset = aSwFields[nPos].nFormatLength;
|
|
sal_uInt32 nValidEntry = 0;
|
|
for (const sal_Int16 nCurrent : aTypes)
|
|
{
|
|
if(nCurrent > NumberingType::CHARS_LOWER_LETTER_N &&
|
|
(nCurrent != (NumberingType::BITMAP | LINK_TOKEN)))
|
|
{
|
|
if (nValidEntry == nFormatId - nOffset)
|
|
{
|
|
sal_uInt32 n = SvxNumberingTypeTable::FindIndex(nCurrent);
|
|
if (n != RESARRAY_INDEX_NOTFOUND)
|
|
{
|
|
aRet = SvxNumberingTypeTable::GetString(n);
|
|
}
|
|
else
|
|
{
|
|
aRet = m_xNumberingInfo->getNumberingIdentifier( nCurrent );
|
|
}
|
|
break;
|
|
}
|
|
++nValidEntry;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return aRet;
|
|
}
|
|
|
|
// determine FormatId from Pseudo-ID
|
|
sal_uInt16 SwFieldMgr::GetFormatId(SwFieldTypesEnum nTypeId, sal_uInt32 nFormatId) const
|
|
{
|
|
sal_uInt16 nId = o3tl::narrowing<sal_uInt16>(nFormatId);
|
|
switch( nTypeId )
|
|
{
|
|
case SwFieldTypesEnum::DocumentInfo:
|
|
{
|
|
TranslateId sId = aSwFields[GetPos(nTypeId)].pFormatResIds[nFormatId];
|
|
if (sId == FMT_REG_AUTHOR)
|
|
nId = DI_SUB_AUTHOR;
|
|
else if (sId == FMT_REG_TIME)
|
|
nId = DI_SUB_TIME;
|
|
else if (sId == FMT_REG_DATE)
|
|
nId = DI_SUB_DATE;
|
|
break;
|
|
}
|
|
case SwFieldTypesEnum::PageNumber:
|
|
case SwFieldTypesEnum::NextPage:
|
|
case SwFieldTypesEnum::PreviousPage:
|
|
case SwFieldTypesEnum::DocumentStatistics:
|
|
case SwFieldTypesEnum::DatabaseSetNumber:
|
|
case SwFieldTypesEnum::Sequence:
|
|
case SwFieldTypesEnum::GetRefPage:
|
|
{
|
|
sal_uInt16 nPos = GetPos(nTypeId);
|
|
if (nFormatId < aSwFields[nPos].nFormatLength)
|
|
{
|
|
const TranslateId sId = aSwFields[nPos].pFormatResIds[nFormatId];
|
|
if (sId == FMT_NUM_ABC)
|
|
nId = SVX_NUM_CHARS_UPPER_LETTER;
|
|
else if (sId == FMT_NUM_SABC)
|
|
nId = SVX_NUM_CHARS_LOWER_LETTER;
|
|
else if (sId == FMT_NUM_ROMAN)
|
|
nId = SVX_NUM_ROMAN_UPPER;
|
|
else if (sId == FMT_NUM_SROMAN)
|
|
nId = SVX_NUM_ROMAN_LOWER;
|
|
else if (sId == FMT_NUM_ARABIC)
|
|
nId = SVX_NUM_ARABIC;
|
|
else if (sId == FMT_NUM_PAGEDESC)
|
|
nId = SVX_NUM_PAGEDESC;
|
|
else if (sId == FMT_NUM_PAGESPECIAL)
|
|
nId = SVX_NUM_CHAR_SPECIAL;
|
|
else if (sId == FMT_NUM_ABC_N)
|
|
nId = SVX_NUM_CHARS_UPPER_LETTER_N;
|
|
else if (sId == FMT_NUM_SABC_N)
|
|
nId = SVX_NUM_CHARS_LOWER_LETTER_N;
|
|
}
|
|
else if (m_xNumberingInfo.is())
|
|
{
|
|
const Sequence<sal_Int16> aTypes = m_xNumberingInfo->getSupportedNumberingTypes();
|
|
sal_Int32 nOffset = aSwFields[nPos].nFormatLength;
|
|
sal_Int32 nValidEntry = 0;
|
|
for (const sal_Int16 nCurrent : aTypes)
|
|
{
|
|
if (nCurrent > NumberingType::CHARS_LOWER_LETTER_N)
|
|
{
|
|
if (nValidEntry == static_cast<sal_Int32>(nFormatId) - nOffset)
|
|
{
|
|
nId = nCurrent;
|
|
break;
|
|
}
|
|
++nValidEntry;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case SwFieldTypesEnum::DDE:
|
|
{
|
|
const TranslateId sId = aSwFields[GetPos(nTypeId)].pFormatResIds[nFormatId];
|
|
if (sId == FMT_DDE_NORMAL)
|
|
nId = static_cast<sal_uInt16>(SfxLinkUpdateMode::ONCALL);
|
|
else if (sId == FMT_DDE_HOT)
|
|
nId = static_cast<sal_uInt16>(SfxLinkUpdateMode::ALWAYS);
|
|
break;
|
|
}
|
|
default: break;
|
|
}
|
|
return nId;
|
|
}
|
|
|
|
// Traveling
|
|
bool SwFieldMgr::GoNextPrev( bool bNext, SwFieldType* pTyp )
|
|
{
|
|
SwWrtShell* pSh = m_pWrtShell ? m_pWrtShell : ::lcl_GetShell();
|
|
if(!pSh)
|
|
return false;
|
|
|
|
if( !pTyp && m_pCurField )
|
|
{
|
|
const SwFieldTypesEnum nTypeId = m_pCurField->GetTypeId();
|
|
if( SwFieldTypesEnum::SetInput == nTypeId || SwFieldTypesEnum::UserInput == nTypeId )
|
|
pTyp = pSh->GetFieldType( 0, SwFieldIds::Input );
|
|
else
|
|
pTyp = m_pCurField->GetTyp();
|
|
}
|
|
|
|
if (pTyp && pTyp->Which() == SwFieldIds::Database)
|
|
{
|
|
// for fieldcommand-edit (hop to all DB fields)
|
|
return pSh->MoveFieldType( nullptr, bNext, SwFieldIds::Database );
|
|
}
|
|
|
|
return pTyp && pSh->MoveFieldType(pTyp, bNext);
|
|
}
|
|
|
|
// insert field types
|
|
void SwFieldMgr::InsertFieldType(SwFieldType const & rType)
|
|
{
|
|
SwWrtShell* pSh = m_pWrtShell ? m_pWrtShell : ::lcl_GetShell();
|
|
OSL_ENSURE(pSh, "no SwWrtShell found");
|
|
if(pSh)
|
|
pSh->InsertFieldType(rType);
|
|
}
|
|
|
|
// determine current TypeId
|
|
SwFieldTypesEnum SwFieldMgr::GetCurTypeId() const
|
|
{
|
|
return m_pCurField ? m_pCurField->GetTypeId() : SwFieldTypesEnum::Unknown;
|
|
}
|
|
|
|
// Over string insert field or update
|
|
bool SwFieldMgr::InsertField(
|
|
SwInsertField_Data& rData)
|
|
{
|
|
std::unique_ptr<SwField> pField;
|
|
bool bExp = false;
|
|
bool bTable = false;
|
|
bool bPageVar = false;
|
|
sal_uInt32 nFormatId = rData.m_nFormatId;
|
|
sal_uInt16 nSubType = rData.m_nSubType;
|
|
sal_Unicode cSeparator = rData.m_cSeparator;
|
|
SwWrtShell* pCurShell = rData.m_pSh;
|
|
if(!pCurShell)
|
|
pCurShell = m_pWrtShell ? m_pWrtShell : ::lcl_GetShell();
|
|
OSL_ENSURE(pCurShell, "no SwWrtShell found");
|
|
if(!pCurShell)
|
|
return false;
|
|
|
|
switch (rData.m_nTypeId)
|
|
{ // ATTENTION this field is inserted by a separate dialog
|
|
case SwFieldTypesEnum::Postit:
|
|
{
|
|
SvtUserOptions aUserOpt;
|
|
SwPostItFieldType* pType = static_cast<SwPostItFieldType*>(pCurShell->GetFieldType(0, SwFieldIds::Postit));
|
|
pField.reset(
|
|
new SwPostItField(
|
|
pType,
|
|
rData.m_sPar1, // author
|
|
rData.m_sPar2, // content
|
|
aUserOpt.GetID(), // author's initials
|
|
OUString(), // name
|
|
DateTime(DateTime::SYSTEM) ));
|
|
}
|
|
break;
|
|
case SwFieldTypesEnum::Script:
|
|
{
|
|
SwScriptFieldType* pType =
|
|
static_cast<SwScriptFieldType*>(pCurShell->GetFieldType(0, SwFieldIds::Script));
|
|
pField.reset(new SwScriptField(pType, rData.m_sPar1, rData.m_sPar2, static_cast<bool>(nFormatId)));
|
|
break;
|
|
}
|
|
|
|
case SwFieldTypesEnum::CombinedChars:
|
|
{
|
|
SwCombinedCharFieldType* pType = static_cast<SwCombinedCharFieldType*>(
|
|
pCurShell->GetFieldType( 0, SwFieldIds::CombinedChars ));
|
|
pField.reset(new SwCombinedCharField( pType, rData.m_sPar1 ));
|
|
}
|
|
break;
|
|
|
|
case SwFieldTypesEnum::Authority:
|
|
{
|
|
SwAuthorityFieldType* pType =
|
|
static_cast<SwAuthorityFieldType*>(pCurShell->GetFieldType(0, SwFieldIds::TableOfAuthorities));
|
|
if (!pType)
|
|
{
|
|
SwAuthorityFieldType const type(pCurShell->GetDoc());
|
|
pType = static_cast<SwAuthorityFieldType*>(
|
|
pCurShell->InsertFieldType(type));
|
|
}
|
|
pField.reset(new SwAuthorityField(pType, rData.m_sPar1));
|
|
}
|
|
break;
|
|
|
|
case SwFieldTypesEnum::Date:
|
|
case SwFieldTypesEnum::Time:
|
|
{
|
|
sal_uInt16 nSub = static_cast< sal_uInt16 >(rData.m_nTypeId == SwFieldTypesEnum::Date ? DATEFLD : TIMEFLD);
|
|
nSub |= nSubType == DATE_VAR ? 0 : FIXEDFLD;
|
|
|
|
SwDateTimeFieldType* pTyp =
|
|
static_cast<SwDateTimeFieldType*>( pCurShell->GetFieldType(0, SwFieldIds::DateTime) );
|
|
pField.reset(new SwDateTimeField(pTyp, nSub, nFormatId));
|
|
pField->SetPar2(rData.m_sPar2);
|
|
break;
|
|
}
|
|
|
|
case SwFieldTypesEnum::Filename:
|
|
{
|
|
SwFileNameFieldType* pTyp =
|
|
static_cast<SwFileNameFieldType*>( pCurShell->GetFieldType(0, SwFieldIds::Filename) );
|
|
pField.reset(new SwFileNameField(pTyp, nFormatId));
|
|
break;
|
|
}
|
|
|
|
case SwFieldTypesEnum::TemplateName:
|
|
{
|
|
SwTemplNameFieldType* pTyp =
|
|
static_cast<SwTemplNameFieldType*>( pCurShell->GetFieldType(0, SwFieldIds::TemplateName) );
|
|
pField.reset(new SwTemplNameField(pTyp, nFormatId));
|
|
break;
|
|
}
|
|
|
|
case SwFieldTypesEnum::Chapter:
|
|
{
|
|
sal_uInt16 nByte = o3tl::narrowing<sal_uInt16>(rData.m_sPar2.toInt32());
|
|
SwChapterFieldType* pTyp =
|
|
static_cast<SwChapterFieldType*>( pCurShell->GetFieldType(0, SwFieldIds::Chapter) );
|
|
pField.reset(new SwChapterField(pTyp, nFormatId));
|
|
nByte = std::max(sal_uInt16(1), nByte);
|
|
nByte = std::min(nByte, sal_uInt16(MAXLEVEL));
|
|
nByte -= 1;
|
|
static_cast<SwChapterField*>(pField.get())->SetLevel(static_cast<sal_uInt8>(nByte));
|
|
break;
|
|
}
|
|
|
|
case SwFieldTypesEnum::NextPage:
|
|
case SwFieldTypesEnum::PreviousPage:
|
|
case SwFieldTypesEnum::PageNumber:
|
|
{
|
|
short nOff = static_cast<short>(rData.m_sPar2.toInt32());
|
|
|
|
if(rData.m_nTypeId == SwFieldTypesEnum::NextPage)
|
|
{
|
|
if( SVX_NUM_CHAR_SPECIAL == nFormatId )
|
|
nOff = 1;
|
|
else
|
|
nOff += 1;
|
|
nSubType = PG_NEXT;
|
|
}
|
|
else if(rData.m_nTypeId == SwFieldTypesEnum::PreviousPage)
|
|
{
|
|
if( SVX_NUM_CHAR_SPECIAL == nFormatId )
|
|
nOff = -1;
|
|
else
|
|
nOff -= 1;
|
|
nSubType = PG_PREV;
|
|
}
|
|
else
|
|
nSubType = PG_RANDOM;
|
|
|
|
SwPageNumberFieldType* pTyp =
|
|
static_cast<SwPageNumberFieldType*>( pCurShell->GetFieldType(0, SwFieldIds::PageNumber) );
|
|
pField.reset(new SwPageNumberField(pTyp, nSubType, nFormatId, nOff));
|
|
|
|
if( SVX_NUM_CHAR_SPECIAL == nFormatId &&
|
|
( PG_PREV == nSubType || PG_NEXT == nSubType ) )
|
|
static_cast<SwPageNumberField*>(pField.get())->SetUserString( rData.m_sPar2 );
|
|
break;
|
|
}
|
|
|
|
case SwFieldTypesEnum::DocumentStatistics:
|
|
{
|
|
SwDocStatFieldType* pTyp =
|
|
static_cast<SwDocStatFieldType*>( pCurShell->GetFieldType(0, SwFieldIds::DocStat) );
|
|
pField.reset(new SwDocStatField(pTyp, nSubType, nFormatId));
|
|
break;
|
|
}
|
|
|
|
case SwFieldTypesEnum::Author:
|
|
{
|
|
SwAuthorFieldType* pTyp =
|
|
static_cast<SwAuthorFieldType*>( pCurShell->GetFieldType(0, SwFieldIds::Author) );
|
|
pField.reset(new SwAuthorField(pTyp, nFormatId));
|
|
break;
|
|
}
|
|
|
|
case SwFieldTypesEnum::ConditionalText:
|
|
case SwFieldTypesEnum::HiddenText:
|
|
{
|
|
SwHiddenTextFieldType* pTyp =
|
|
static_cast<SwHiddenTextFieldType*>( pCurShell->GetFieldType(0, SwFieldIds::HiddenText) );
|
|
pField.reset(new SwHiddenTextField(pTyp, true, rData.m_sPar1, rData.m_sPar2, false, rData.m_nTypeId));
|
|
bExp = true;
|
|
break;
|
|
}
|
|
|
|
case SwFieldTypesEnum::HiddenParagraph:
|
|
{
|
|
SwHiddenParaFieldType* pTyp =
|
|
static_cast<SwHiddenParaFieldType*>( pCurShell->GetFieldType(0, SwFieldIds::HiddenPara) );
|
|
pField.reset(new SwHiddenParaField(pTyp, rData.m_sPar1));
|
|
bExp = true;
|
|
break;
|
|
}
|
|
|
|
case SwFieldTypesEnum::SetRef:
|
|
{
|
|
if( !rData.m_sPar1.isEmpty() && CanInsertRefMark( rData.m_sPar1 ) )
|
|
{
|
|
const OUString& rRefmarkText = rData.m_sPar2;
|
|
SwPaM* pCursorPos = pCurShell->GetCursor();
|
|
pCurShell->StartAction();
|
|
bool bHadMark = pCursorPos->HasMark();
|
|
// If we have no selection and the refmark text is provided, then the text is
|
|
// expected to be HTML.
|
|
if (!bHadMark && !rRefmarkText.isEmpty())
|
|
{
|
|
// Split node to remember where the start position is.
|
|
bool bSuccess = pCurShell->GetDoc()->getIDocumentContentOperations().SplitNode(
|
|
*pCursorPos->GetPoint(), /*bChkTableStart=*/false);
|
|
if (bSuccess)
|
|
{
|
|
SwPaM aRefmarkPam(*pCursorPos->GetPoint());
|
|
aRefmarkPam.Move(fnMoveBackward, GoInContent);
|
|
|
|
// Paste HTML content.
|
|
SwTranslateHelper::PasteHTMLToPaM(
|
|
*pCurShell, pCursorPos, rRefmarkText.toUtf8());
|
|
|
|
// Undo the above SplitNode().
|
|
aRefmarkPam.SetMark();
|
|
aRefmarkPam.Move(fnMoveForward, GoInContent);
|
|
pCurShell->GetDoc()->getIDocumentContentOperations().DeleteAndJoin(
|
|
aRefmarkPam);
|
|
*aRefmarkPam.GetMark() = *pCursorPos->GetPoint();
|
|
*pCursorPos = aRefmarkPam;
|
|
}
|
|
}
|
|
|
|
pCurShell->SetAttrItem( SwFormatRefMark( rData.m_sPar1 ) );
|
|
|
|
if (!bHadMark && !rRefmarkText.isEmpty())
|
|
{
|
|
pCursorPos->DeleteMark();
|
|
}
|
|
pCurShell->EndAction();
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
case SwFieldTypesEnum::GetRef:
|
|
{
|
|
SwGetRefFieldType* pTyp =
|
|
static_cast<SwGetRefFieldType*>( pCurShell->GetFieldType(0, SwFieldIds::GetRef) );
|
|
|
|
sal_uInt16 nSeqNo = 0;
|
|
sal_uInt16 nFlags = 0;
|
|
|
|
if (nSubType == REF_STYLE) nFlags = o3tl::narrowing<sal_uInt16>(rData.m_sPar2.toInt32());
|
|
else nSeqNo = o3tl::narrowing<sal_uInt16>(rData.m_sPar2.toInt32());
|
|
|
|
OUString sReferenceLanguage;
|
|
// handle language-variant formats
|
|
if (nFormatId >= SAL_N_ELEMENTS(FMT_REF_ARY))
|
|
{
|
|
LanguageType nLang = GetCurrLanguage();
|
|
if (nLang == LANGUAGE_HUNGARIAN)
|
|
{
|
|
if (nFormatId >= SAL_N_ELEMENTS(FMT_REF_ARY) * 2)
|
|
sReferenceLanguage = "Hu";
|
|
else
|
|
sReferenceLanguage = "hu";
|
|
}
|
|
nFormatId %= SAL_N_ELEMENTS(FMT_REF_ARY);
|
|
}
|
|
|
|
pField.reset(new SwGetRefField(pTyp, rData.m_sPar1, sReferenceLanguage, nSubType, nSeqNo, nFlags, nFormatId));
|
|
bExp = true;
|
|
break;
|
|
}
|
|
|
|
case SwFieldTypesEnum::DDE:
|
|
{
|
|
//JP 28.08.95: DDE-Topics/-Items can have blanks in their names!
|
|
// That's not yet considered here.
|
|
sal_Int32 nIndex = 0;
|
|
OUString sCmd = rData.m_sPar2.replaceFirst(" ", OUStringChar(sfx2::cTokenSeparator), &nIndex);
|
|
if (nIndex>=0 && ++nIndex<sCmd.getLength())
|
|
{
|
|
sCmd = sCmd.replaceFirst(" ", OUStringChar(sfx2::cTokenSeparator), &nIndex);
|
|
}
|
|
|
|
SwDDEFieldType aType( rData.m_sPar1, sCmd, static_cast<SfxLinkUpdateMode>(nFormatId) );
|
|
SwDDEFieldType* pTyp = static_cast<SwDDEFieldType*>( pCurShell->InsertFieldType( aType ) );
|
|
pField.reset(new SwDDEField( pTyp ));
|
|
break;
|
|
}
|
|
|
|
case SwFieldTypesEnum::Macro:
|
|
{
|
|
SwMacroFieldType* pTyp =
|
|
static_cast<SwMacroFieldType*>(pCurShell->GetFieldType(0, SwFieldIds::Macro));
|
|
|
|
pField.reset(new SwMacroField(pTyp, rData.m_sPar1, rData.m_sPar2));
|
|
|
|
break;
|
|
}
|
|
|
|
case SwFieldTypesEnum::Internet:
|
|
{
|
|
SwFormatINetFormat aFormat( rData.m_sPar1, m_sCurFrame );
|
|
return pCurShell->InsertURL( aFormat, rData.m_sPar2 );
|
|
}
|
|
|
|
case SwFieldTypesEnum::JumpEdit:
|
|
{
|
|
SwJumpEditFieldType* pTyp =
|
|
static_cast<SwJumpEditFieldType*>(pCurShell->GetFieldType(0, SwFieldIds::JumpEdit));
|
|
|
|
pField.reset(new SwJumpEditField(pTyp, nFormatId, rData.m_sPar1, rData.m_sPar2));
|
|
break;
|
|
}
|
|
|
|
case SwFieldTypesEnum::DocumentInfo:
|
|
{
|
|
SwDocInfoFieldType* pTyp = static_cast<SwDocInfoFieldType*>( pCurShell->GetFieldType(
|
|
0, SwFieldIds::DocInfo ) );
|
|
pField.reset(new SwDocInfoField(pTyp, nSubType, rData.m_sPar1, nFormatId));
|
|
break;
|
|
}
|
|
|
|
case SwFieldTypesEnum::ExtendedUser:
|
|
{
|
|
SwExtUserFieldType* pTyp = static_cast<SwExtUserFieldType*>( pCurShell->GetFieldType(
|
|
0, SwFieldIds::ExtUser) );
|
|
pField.reset(new SwExtUserField(pTyp, nSubType, nFormatId));
|
|
break;
|
|
}
|
|
|
|
case SwFieldTypesEnum::Database:
|
|
{
|
|
#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
|
|
SwDBData aDBData;
|
|
OUString sPar1;
|
|
|
|
if (rData.m_sPar1.indexOf(DB_DELIM)<0)
|
|
{
|
|
aDBData = pCurShell->GetDBData();
|
|
sPar1 = rData.m_sPar1;
|
|
}
|
|
else
|
|
{
|
|
sal_Int32 nIdx{ 0 };
|
|
aDBData.sDataSource = rData.m_sPar1.getToken(0, DB_DELIM, nIdx);
|
|
aDBData.sCommand = rData.m_sPar1.getToken(0, DB_DELIM, nIdx);
|
|
aDBData.nCommandType = o3tl::toInt32(o3tl::getToken(rData.m_sPar1, 0, DB_DELIM, nIdx));
|
|
sPar1 = rData.m_sPar1.getToken(0, DB_DELIM, nIdx);
|
|
}
|
|
|
|
if(!aDBData.sDataSource.isEmpty() && pCurShell->GetDBData() != aDBData)
|
|
pCurShell->ChgDBData(aDBData);
|
|
|
|
SwDBFieldType* pTyp = static_cast<SwDBFieldType*>(pCurShell->InsertFieldType(
|
|
SwDBFieldType(pCurShell->GetDoc(), sPar1, aDBData) ) );
|
|
pField.reset(new SwDBField(pTyp));
|
|
pField->SetSubType(nSubType);
|
|
|
|
if( !(nSubType & nsSwExtendedSubType::SUB_OWN_FMT) ) // determine database format
|
|
{
|
|
Reference< XDataSource> xSource;
|
|
rData.m_aDBDataSource >>= xSource;
|
|
Reference<XConnection> xConnection;
|
|
rData.m_aDBConnection >>= xConnection;
|
|
Reference<XPropertySet> xColumn;
|
|
rData.m_aDBColumn >>= xColumn;
|
|
if(xColumn.is())
|
|
{
|
|
nFormatId = SwDBManager::GetColumnFormat(xSource, xConnection, xColumn,
|
|
pCurShell->GetNumberFormatter(), GetCurrLanguage() );
|
|
}
|
|
else
|
|
nFormatId = pCurShell->GetDBManager()->GetColumnFormat(
|
|
aDBData.sDataSource, aDBData.sCommand, sPar1,
|
|
pCurShell->GetNumberFormatter(), GetCurrLanguage() );
|
|
}
|
|
pField->ChangeFormat( nFormatId );
|
|
|
|
bExp = true;
|
|
#endif
|
|
break;
|
|
}
|
|
|
|
case SwFieldTypesEnum::DatabaseSetNumber:
|
|
case SwFieldTypesEnum::DatabaseNumberSet:
|
|
case SwFieldTypesEnum::DatabaseNextSet:
|
|
case SwFieldTypesEnum::DatabaseName:
|
|
{
|
|
#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
|
|
SwDBData aDBData;
|
|
|
|
// extract DBName from rData.m_sPar1. Format: DBName.TableName.CommandType.ExpStrg
|
|
sal_Int32 nTablePos = rData.m_sPar1.indexOf(DB_DELIM);
|
|
sal_Int32 nExpPos = -1;
|
|
|
|
if (nTablePos>=0)
|
|
{
|
|
aDBData.sDataSource = rData.m_sPar1.copy(0, nTablePos++);
|
|
sal_Int32 nCmdTypePos = rData.m_sPar1.indexOf(DB_DELIM, nTablePos);
|
|
if (nCmdTypePos>=0)
|
|
{
|
|
aDBData.sCommand = rData.m_sPar1.copy(nTablePos, nCmdTypePos++ - nTablePos);
|
|
nExpPos = rData.m_sPar1.indexOf(DB_DELIM, nCmdTypePos);
|
|
if (nExpPos>=0)
|
|
{
|
|
aDBData.nCommandType = o3tl::toInt32(rData.m_sPar1.subView(nCmdTypePos, nExpPos++ - nCmdTypePos));
|
|
}
|
|
}
|
|
}
|
|
|
|
sal_Int32 nPos = 0;
|
|
if (nExpPos>=0)
|
|
nPos = nExpPos;
|
|
else if (nTablePos>=0)
|
|
nPos = nTablePos;
|
|
|
|
OUString sPar1 = rData.m_sPar1.copy(nPos);
|
|
|
|
if (!aDBData.sDataSource.isEmpty() && pCurShell->GetDBData() != aDBData)
|
|
pCurShell->ChgDBData(aDBData);
|
|
|
|
switch(rData.m_nTypeId)
|
|
{
|
|
case SwFieldTypesEnum::DatabaseName:
|
|
{
|
|
SwDBNameFieldType* pTyp =
|
|
static_cast<SwDBNameFieldType*>(pCurShell->GetFieldType(0, SwFieldIds::DatabaseName));
|
|
pField.reset(new SwDBNameField(pTyp, aDBData));
|
|
|
|
break;
|
|
}
|
|
case SwFieldTypesEnum::DatabaseNextSet:
|
|
{
|
|
SwDBNextSetFieldType* pTyp = static_cast<SwDBNextSetFieldType*>(pCurShell->GetFieldType(
|
|
0, SwFieldIds::DbNextSet) );
|
|
pField.reset(new SwDBNextSetField(pTyp, sPar1, aDBData));
|
|
bExp = true;
|
|
break;
|
|
}
|
|
case SwFieldTypesEnum::DatabaseNumberSet:
|
|
{
|
|
SwDBNumSetFieldType* pTyp = static_cast<SwDBNumSetFieldType*>( pCurShell->GetFieldType(
|
|
0, SwFieldIds::DbNumSet) );
|
|
pField.reset(new SwDBNumSetField( pTyp, sPar1, rData.m_sPar2, aDBData));
|
|
bExp = true;
|
|
break;
|
|
}
|
|
case SwFieldTypesEnum::DatabaseSetNumber:
|
|
{
|
|
SwDBSetNumberFieldType* pTyp = static_cast<SwDBSetNumberFieldType*>(
|
|
pCurShell->GetFieldType(0, SwFieldIds::DbSetNumber) );
|
|
pField.reset(new SwDBSetNumberField( pTyp, aDBData, nFormatId));
|
|
bExp = true;
|
|
break;
|
|
}
|
|
default: break;
|
|
}
|
|
#endif
|
|
break;
|
|
}
|
|
|
|
case SwFieldTypesEnum::User:
|
|
{
|
|
SwUserFieldType* pTyp =
|
|
static_cast<SwUserFieldType*>( pCurShell->GetFieldType(SwFieldIds::User, rData.m_sPar1) );
|
|
|
|
// only if existing
|
|
if(!pTyp)
|
|
{
|
|
pTyp = static_cast<SwUserFieldType*>( pCurShell->InsertFieldType(
|
|
SwUserFieldType(pCurShell->GetDoc(), rData.m_sPar1)) );
|
|
}
|
|
if (pTyp->GetContent(nFormatId) != rData.m_sPar2)
|
|
pTyp->SetContent(rData.m_sPar2, nFormatId);
|
|
pField.reset(new SwUserField(pTyp, 0, nFormatId));
|
|
if (pField->GetSubType() != nSubType)
|
|
pField->SetSubType(nSubType);
|
|
bTable = true;
|
|
break;
|
|
}
|
|
|
|
case SwFieldTypesEnum::Input:
|
|
{
|
|
if ((nSubType & 0x00ff) == INP_VAR)
|
|
{
|
|
SwSetExpFieldType* pTyp = static_cast<SwSetExpFieldType*>(
|
|
pCurShell->GetFieldType(SwFieldIds::SetExp, rData.m_sPar1) );
|
|
|
|
// no Expression Type with this name existing -> create
|
|
if(pTyp)
|
|
{
|
|
std::unique_ptr<SwSetExpField> pExpField(
|
|
new SwSetExpField(pTyp, OUString(), nFormatId));
|
|
|
|
// Don't change type of SwSetExpFieldType:
|
|
sal_uInt16 nOldSubType = pExpField->GetSubType();
|
|
pExpField->SetSubType(nOldSubType | (nSubType & 0xff00));
|
|
|
|
pExpField->SetPromptText(rData.m_sPar2);
|
|
pExpField->SetInputFlag(true) ;
|
|
bExp = true;
|
|
pField = std::move(pExpField);
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
SwInputFieldType* pTyp =
|
|
static_cast<SwInputFieldType*>( pCurShell->GetFieldType(0, SwFieldIds::Input) );
|
|
|
|
pField.reset(
|
|
new SwInputField( pTyp, rData.m_sPar1, rData.m_sPar2, nSubType|nsSwExtendedSubType::SUB_INVISIBLE, nFormatId));
|
|
}
|
|
break;
|
|
}
|
|
|
|
case SwFieldTypesEnum::Set:
|
|
{
|
|
if (rData.m_sPar2.isEmpty()) // empty variables are not allowed
|
|
return false;
|
|
|
|
SwSetExpFieldType* pTyp = static_cast<SwSetExpFieldType*>( pCurShell->InsertFieldType(
|
|
SwSetExpFieldType(pCurShell->GetDoc(), rData.m_sPar1) ) );
|
|
|
|
std::unique_ptr<SwSetExpField> pExpField(new SwSetExpField( pTyp, rData.m_sPar2, nFormatId));
|
|
pExpField->SetSubType(nSubType);
|
|
pExpField->SetPar2(rData.m_sPar2);
|
|
bExp = true;
|
|
pField = std::move(pExpField);
|
|
break;
|
|
}
|
|
|
|
case SwFieldTypesEnum::Sequence:
|
|
{
|
|
SwSetExpFieldType* pTyp = static_cast<SwSetExpFieldType*>( pCurShell->InsertFieldType(
|
|
SwSetExpFieldType(pCurShell->GetDoc(), rData.m_sPar1, nsSwGetSetExpType::GSE_SEQ)));
|
|
|
|
sal_uInt8 nLevel = static_cast< sal_uInt8 >(nSubType & 0xff);
|
|
|
|
pTyp->SetOutlineLvl(nLevel);
|
|
if (nLevel != 0x7f && cSeparator == 0)
|
|
cSeparator = '.';
|
|
|
|
pTyp->SetDelimiter(OUString(cSeparator));
|
|
pField.reset(new SwSetExpField(pTyp, rData.m_sPar2, nFormatId));
|
|
bExp = true;
|
|
break;
|
|
}
|
|
|
|
case SwFieldTypesEnum::Get:
|
|
{
|
|
// is there a corresponding SetField
|
|
SwSetExpFieldType* pSetTyp = static_cast<SwSetExpFieldType*>(
|
|
pCurShell->GetFieldType(SwFieldIds::SetExp, rData.m_sPar1));
|
|
|
|
if(pSetTyp)
|
|
{
|
|
SwGetExpFieldType* pTyp = static_cast<SwGetExpFieldType*>( pCurShell->GetFieldType(
|
|
0, SwFieldIds::GetExp) );
|
|
pField.reset( new SwGetExpField(pTyp, rData.m_sPar1, pSetTyp->GetType(), nFormatId) );
|
|
pField->SetSubType(nSubType | pSetTyp->GetType());
|
|
bExp = true;
|
|
}
|
|
else
|
|
return false;
|
|
break;
|
|
}
|
|
|
|
case SwFieldTypesEnum::Formel:
|
|
{
|
|
if(pCurShell->GetFrameType(nullptr,false) & FrameTypeFlags::TABLE)
|
|
{
|
|
pCurShell->StartAllAction();
|
|
|
|
SvNumberFormatter* pFormatter = pCurShell->GetDoc()->GetNumberFormatter();
|
|
const SvNumberformat* pEntry = pFormatter->GetEntry(nFormatId);
|
|
|
|
if (pEntry)
|
|
{
|
|
SfxStringItem aFormat(FN_NUMBER_FORMAT, pEntry->GetFormatstring());
|
|
pCurShell->GetView().GetViewFrame().GetDispatcher()->
|
|
ExecuteList(FN_NUMBER_FORMAT, SfxCallMode::SYNCHRON,
|
|
{ &aFormat });
|
|
}
|
|
|
|
SfxItemSetFixed<RES_BOXATR_FORMULA, RES_BOXATR_FORMULA> aBoxSet( pCurShell->GetAttrPool() );
|
|
|
|
OUString sFormula(comphelper::string::stripStart(rData.m_sPar2, ' '));
|
|
if ( sFormula.startsWith("=") )
|
|
{
|
|
sFormula = sFormula.copy(1);
|
|
}
|
|
|
|
aBoxSet.Put( SwTableBoxFormula( sFormula ));
|
|
pCurShell->SetTableBoxFormulaAttrs( aBoxSet );
|
|
pCurShell->UpdateTable();
|
|
|
|
pCurShell->EndAllAction();
|
|
return true;
|
|
|
|
}
|
|
else
|
|
{
|
|
SwGetExpFieldType* pTyp = static_cast<SwGetExpFieldType*>(
|
|
pCurShell->GetFieldType(0, SwFieldIds::GetExp) );
|
|
pField.reset( new SwGetExpField(pTyp, rData.m_sPar2, nsSwGetSetExpType::GSE_FORMULA, nFormatId) );
|
|
pField->SetSubType(nSubType);
|
|
bExp = true;
|
|
}
|
|
break;
|
|
}
|
|
case SwFieldTypesEnum::SetRefPage:
|
|
pField.reset( new SwRefPageSetField( static_cast<SwRefPageSetFieldType*>(
|
|
pCurShell->GetFieldType( 0, SwFieldIds::RefPageSet ) ),
|
|
static_cast<short>(rData.m_sPar2.toInt32()), 0 != nSubType ) );
|
|
bPageVar = true;
|
|
break;
|
|
|
|
case SwFieldTypesEnum::GetRefPage:
|
|
pField.reset( new SwRefPageGetField( static_cast<SwRefPageGetFieldType*>(
|
|
pCurShell->GetFieldType( 0, SwFieldIds::RefPageGet ) ), nFormatId ) );
|
|
bPageVar = true;
|
|
break;
|
|
case SwFieldTypesEnum::Dropdown :
|
|
{
|
|
pField.reset( new SwDropDownField(pCurShell->GetFieldType( 0, SwFieldIds::Dropdown )) );
|
|
const sal_Int32 nTokenCount = comphelper::string::getTokenCount(rData.m_sPar2, DB_DELIM);
|
|
Sequence<OUString> aEntries(nTokenCount);
|
|
OUString* pArray = aEntries.getArray();
|
|
for(sal_Int32 nToken = 0, nIdx = 0; nToken < nTokenCount; nToken++)
|
|
pArray[nToken] = rData.m_sPar2.getToken(0, DB_DELIM, nIdx);
|
|
static_cast<SwDropDownField*>(pField.get())->SetItems(aEntries);
|
|
static_cast<SwDropDownField*>(pField.get())->SetName(rData.m_sPar1);
|
|
}
|
|
break;
|
|
|
|
// Insert Paragraph Signature field by signing the paragraph.
|
|
// The resulting field is really a metadata field, created and added via signing.
|
|
case SwFieldTypesEnum::ParagraphSignature:
|
|
pCurShell->SignParagraph();
|
|
return true;
|
|
|
|
default:
|
|
{ OSL_ENSURE(false, "wrong field type");
|
|
return false;
|
|
}
|
|
}
|
|
OSL_ENSURE(pField, "field not available");
|
|
|
|
//the auto language flag has to be set prior to the language!
|
|
pField->SetAutomaticLanguage(rData.m_bIsAutomaticLanguage);
|
|
LanguageType nLang = GetCurrLanguage();
|
|
pField->SetLanguage(nLang);
|
|
|
|
// insert
|
|
pCurShell->StartAllAction();
|
|
|
|
bool const isSuccess = pCurShell->InsertField2(*pField, rData.m_oAnnotationRange ? &*rData.m_oAnnotationRange : nullptr);
|
|
|
|
if (isSuccess)
|
|
{
|
|
if (SwFieldTypesEnum::Input == rData.m_nTypeId)
|
|
{
|
|
pCurShell->Push();
|
|
|
|
// start dialog, not before the field is inserted tdf#99529
|
|
pCurShell->Left(SwCursorSkipMode::Chars, false,
|
|
(INP_VAR == (nSubType & 0xff) || pCurShell->GetViewOptions()->IsFieldName()) ? 1 : 2,
|
|
false);
|
|
pCurShell->StartInputFieldDlg(pField.get(), false, true, rData.m_pParent);
|
|
|
|
pCurShell->Pop(SwCursorShell::PopMode::DeleteCurrent);
|
|
}
|
|
|
|
if (bExp && m_bEvalExp)
|
|
{
|
|
pCurShell->UpdateExpFields(true);
|
|
}
|
|
|
|
if (bTable)
|
|
{
|
|
pCurShell->Left(SwCursorSkipMode::Chars, false, 1, false );
|
|
pCurShell->UpdateOneField(*pField);
|
|
pCurShell->Right(SwCursorSkipMode::Chars, false, 1, false );
|
|
}
|
|
else if (bPageVar)
|
|
{
|
|
static_cast<SwRefPageGetFieldType*>(pCurShell->GetFieldType(0, SwFieldIds::RefPageGet))->UpdateFields();
|
|
}
|
|
else if (SwFieldTypesEnum::GetRef == rData.m_nTypeId)
|
|
{
|
|
pField->GetTyp()->UpdateFields();
|
|
}
|
|
}
|
|
|
|
// delete temporary field
|
|
pField.reset();
|
|
|
|
pCurShell->EndAllAction();
|
|
return isSuccess;
|
|
}
|
|
|
|
// fields update
|
|
void SwFieldMgr::UpdateCurField(sal_uInt32 nFormat,
|
|
const OUString& rPar1,
|
|
const OUString& rPar2,
|
|
std::unique_ptr<SwField> pTmpField)
|
|
{
|
|
// change format
|
|
OSL_ENSURE(m_pCurField, "no field at CursorPos");
|
|
|
|
if (!pTmpField)
|
|
pTmpField = m_pCurField->CopyField();
|
|
|
|
SwFieldType* pType = pTmpField->GetTyp();
|
|
const SwFieldTypesEnum nTypeId = pTmpField->GetTypeId();
|
|
|
|
SwWrtShell* pSh = m_pWrtShell ? m_pWrtShell : ::lcl_GetShell();
|
|
OSL_ENSURE(pSh, "no SwWrtShell found");
|
|
if(!pSh)
|
|
return;
|
|
pSh->StartAllAction();
|
|
|
|
bool bSetPar2 = true;
|
|
bool bSetPar1 = true;
|
|
OUString sPar2( rPar2 );
|
|
|
|
// Order to Format
|
|
switch( nTypeId )
|
|
{
|
|
case SwFieldTypesEnum::DDE:
|
|
{
|
|
// DDE-Topics/-Items can have blanks in their names!
|
|
// That's not yet considered here!
|
|
sal_Int32 nIndex = 0;
|
|
sPar2 = sPar2.replaceFirst(" ", OUStringChar(sfx2::cTokenSeparator), &nIndex );
|
|
if (nIndex>=0 && ++nIndex<sPar2.getLength())
|
|
{
|
|
sPar2 = sPar2.replaceFirst(" ", OUStringChar(sfx2::cTokenSeparator), &nIndex);
|
|
}
|
|
break;
|
|
}
|
|
|
|
case SwFieldTypesEnum::Chapter:
|
|
{
|
|
sal_uInt16 nByte = o3tl::narrowing<sal_uInt16>(rPar2.toInt32());
|
|
nByte = std::max(sal_uInt16(1), nByte);
|
|
nByte = std::min(nByte, sal_uInt16(MAXLEVEL));
|
|
nByte -= 1;
|
|
static_cast<SwChapterField*>(pTmpField.get())->SetLevel(static_cast<sal_uInt8>(nByte));
|
|
bSetPar2 = false;
|
|
break;
|
|
}
|
|
|
|
case SwFieldTypesEnum::Script:
|
|
static_cast<SwScriptField*>(pTmpField.get())->SetCodeURL(static_cast<bool>(nFormat));
|
|
break;
|
|
|
|
case SwFieldTypesEnum::NextPage:
|
|
if( SVX_NUM_CHAR_SPECIAL == nFormat )
|
|
{
|
|
static_cast<SwPageNumberField*>(m_pCurField)->SetUserString( sPar2 );
|
|
sPar2 = "1";
|
|
}
|
|
else
|
|
{
|
|
if( nFormat + 2 == SVX_NUM_PAGEDESC )
|
|
nFormat = SVX_NUM_PAGEDESC;
|
|
short nOff = static_cast<short>(sPar2.toInt32());
|
|
nOff += 1;
|
|
sPar2 = OUString::number(nOff);
|
|
}
|
|
break;
|
|
|
|
case SwFieldTypesEnum::PreviousPage:
|
|
if( SVX_NUM_CHAR_SPECIAL == nFormat )
|
|
{
|
|
static_cast<SwPageNumberField*>(m_pCurField)->SetUserString( sPar2 );
|
|
sPar2 = "-1";
|
|
}
|
|
else
|
|
{
|
|
if( nFormat + 2 == SVX_NUM_PAGEDESC )
|
|
nFormat = SVX_NUM_PAGEDESC;
|
|
short nOff = static_cast<short>(sPar2.toInt32());
|
|
nOff -= 1;
|
|
sPar2 = OUString::number(nOff);
|
|
}
|
|
break;
|
|
|
|
case SwFieldTypesEnum::PageNumber:
|
|
case SwFieldTypesEnum::GetRefPage:
|
|
if( nFormat + 2 == SVX_NUM_PAGEDESC )
|
|
nFormat = SVX_NUM_PAGEDESC;
|
|
break;
|
|
|
|
case SwFieldTypesEnum::GetRef:
|
|
{
|
|
bSetPar2 = false;
|
|
sal_Int16 nSubType = o3tl::narrowing<sal_uInt16>(rPar2.toInt32());
|
|
static_cast<SwGetRefField*>(pTmpField.get())->SetSubType( nSubType );
|
|
const sal_Int32 nPos = rPar2.indexOf( '|' );
|
|
if( nPos>=0 )
|
|
switch (nSubType) {
|
|
case REF_STYLE:
|
|
static_cast<SwGetRefField*>(pTmpField.get())->SetFlags( o3tl::narrowing<sal_uInt16>(o3tl::toInt32(rPar2.subView( nPos + 1 ))));
|
|
break;
|
|
default:
|
|
static_cast<SwGetRefField*>(pTmpField.get())->SetSeqNo( o3tl::narrowing<sal_uInt16>(o3tl::toInt32(rPar2.subView( nPos + 1 ))));
|
|
}
|
|
}
|
|
break;
|
|
case SwFieldTypesEnum::Dropdown:
|
|
{
|
|
sal_Int32 nTokenCount = comphelper::string::getTokenCount(sPar2, DB_DELIM);
|
|
Sequence<OUString> aEntries(nTokenCount);
|
|
OUString* pArray = aEntries.getArray();
|
|
for(sal_Int32 nToken = 0, nIdx = 0; nToken < nTokenCount; nToken++)
|
|
pArray[nToken] = sPar2.getToken(0, DB_DELIM, nIdx);
|
|
static_cast<SwDropDownField*>(pTmpField.get())->SetItems(aEntries);
|
|
static_cast<SwDropDownField*>(pTmpField.get())->SetName(rPar1);
|
|
bSetPar1 = bSetPar2 = false;
|
|
}
|
|
break;
|
|
case SwFieldTypesEnum::Authority :
|
|
{
|
|
//#i99069# changes to a bibliography field should change the field type
|
|
SwAuthorityField* pAuthorityField = static_cast<SwAuthorityField*>(pTmpField.get());
|
|
SwAuthorityFieldType* pAuthorityType = static_cast<SwAuthorityFieldType*>(pType);
|
|
rtl::Reference<SwAuthEntry> xTempEntry(new SwAuthEntry);
|
|
for( sal_Int32 i = 0, nIdx = 0; i < AUTH_FIELD_END; ++i )
|
|
xTempEntry->SetAuthorField( static_cast<ToxAuthorityField>(i),
|
|
rPar1.getToken( 0, TOX_STYLE_DELIMITER, nIdx ));
|
|
|
|
// If just the page number of the URL changed, then update the current field and not
|
|
// others.
|
|
bool bEquivalent = true;
|
|
for (int i = 0; i < AUTH_FIELD_END; ++i)
|
|
{
|
|
auto eField = static_cast<ToxAuthorityField>(i);
|
|
if (eField == AUTH_FIELD_URL)
|
|
{
|
|
if (SwTOXAuthority::GetSourceURL(xTempEntry->GetAuthorField(AUTH_FIELD_URL))
|
|
!= SwTOXAuthority::GetSourceURL(
|
|
pAuthorityField->GetFieldText(AUTH_FIELD_URL)))
|
|
{
|
|
bEquivalent = false;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (xTempEntry->GetAuthorField(eField) != pAuthorityField->GetFieldText(eField))
|
|
{
|
|
bEquivalent = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (bEquivalent)
|
|
{
|
|
break;
|
|
}
|
|
|
|
if( pAuthorityType->ChangeEntryContent( xTempEntry.get() ) )
|
|
{
|
|
pType->UpdateFields();
|
|
pSh->SetModified();
|
|
}
|
|
|
|
if( xTempEntry->GetAuthorField( AUTH_FIELD_IDENTIFIER ) ==
|
|
pAuthorityField->GetFieldText( AUTH_FIELD_IDENTIFIER ) )
|
|
bSetPar1 = false; //otherwise it's a new or changed entry, the field needs to be updated
|
|
bSetPar2 = false;
|
|
}
|
|
break;
|
|
default: break;
|
|
}
|
|
|
|
// set format
|
|
// setup format before SetPar2 because of NumberFormatter!
|
|
pTmpField->ChangeFormat(nFormat);
|
|
|
|
if( bSetPar1 )
|
|
pTmpField->SetPar1( rPar1 );
|
|
if( bSetPar2 )
|
|
pTmpField->SetPar2( sPar2 );
|
|
|
|
// kick off update
|
|
if(nTypeId == SwFieldTypesEnum::DDE ||
|
|
nTypeId == SwFieldTypesEnum::User ||
|
|
nTypeId == SwFieldTypesEnum::UserInput)
|
|
{
|
|
pType->UpdateFields();
|
|
pSh->SetModified();
|
|
}
|
|
else {
|
|
// mb: #32157
|
|
pSh->SwEditShell::UpdateOneField(*pTmpField);
|
|
GetCurField();
|
|
}
|
|
|
|
pTmpField.reset();
|
|
|
|
pSh->EndAllAction();
|
|
}
|
|
|
|
// explicitly evaluate ExpressionFields
|
|
void SwFieldMgr::EvalExpFields(SwWrtShell* pSh)
|
|
{
|
|
if (pSh == nullptr)
|
|
pSh = m_pWrtShell ? m_pWrtShell : ::lcl_GetShell();
|
|
|
|
if(pSh)
|
|
{
|
|
pSh->StartAllAction();
|
|
pSh->UpdateExpFields(true);
|
|
pSh->EndAllAction();
|
|
}
|
|
}
|
|
LanguageType SwFieldMgr::GetCurrLanguage() const
|
|
{
|
|
SwWrtShell* pSh = m_pWrtShell ? m_pWrtShell : ::lcl_GetShell();
|
|
if( pSh )
|
|
return pSh->GetCurLang();
|
|
return SvtSysLocale().GetLanguageTag().getLanguageType();
|
|
}
|
|
|
|
void SwFieldType::GetFieldName_()
|
|
{
|
|
static const TranslateId coFieldNms[] =
|
|
{
|
|
FLD_DATE_STD,
|
|
FLD_TIME_STD,
|
|
STR_FILENAMEFLD,
|
|
STR_DBNAMEFLD,
|
|
STR_CHAPTERFLD,
|
|
STR_PAGENUMBERFLD,
|
|
STR_DOCSTATFLD,
|
|
STR_AUTHORFLD,
|
|
STR_SETFLD,
|
|
STR_GETFLD,
|
|
STR_FORMELFLD,
|
|
STR_HIDDENTXTFLD,
|
|
STR_SETREFFLD,
|
|
STR_GETREFFLD,
|
|
STR_DDEFLD,
|
|
STR_MACROFLD,
|
|
STR_INPUTFLD,
|
|
STR_HIDDENPARAFLD,
|
|
STR_DOCINFOFLD,
|
|
STR_DBFLD,
|
|
STR_USERFLD,
|
|
STR_POSTITFLD,
|
|
STR_TEMPLNAMEFLD,
|
|
STR_SEQFLD,
|
|
STR_DBNEXTSETFLD,
|
|
STR_DBNUMSETFLD,
|
|
STR_DBSETNUMBERFLD,
|
|
STR_CONDTXTFLD,
|
|
STR_NEXTPAGEFLD,
|
|
STR_PREVPAGEFLD,
|
|
STR_EXTUSERFLD,
|
|
FLD_DATE_FIX,
|
|
FLD_TIME_FIX,
|
|
STR_SETINPUTFLD,
|
|
STR_USRINPUTFLD,
|
|
STR_SETREFPAGEFLD,
|
|
STR_GETREFPAGEFLD,
|
|
STR_INTERNETFLD,
|
|
STR_JUMPEDITFLD,
|
|
STR_SCRIPTFLD,
|
|
STR_AUTHORITY,
|
|
STR_COMBINED_CHARS,
|
|
STR_DROPDOWN,
|
|
STR_CUSTOM_FIELD,
|
|
STR_PARAGRAPH_SIGNATURE
|
|
};
|
|
|
|
// insert infos for fields
|
|
SwFieldType::s_pFieldNames = new std::vector<OUString>;
|
|
SwFieldType::s_pFieldNames->reserve(SAL_N_ELEMENTS(coFieldNms));
|
|
for (const TranslateId & id : coFieldNms)
|
|
{
|
|
const OUString aTmp(SwResId(id));
|
|
SwFieldType::s_pFieldNames->push_back(MnemonicGenerator::EraseAllMnemonicChars( aTmp ));
|
|
}
|
|
}
|
|
|
|
bool SwFieldMgr::ChooseMacro(weld::Window* pDialogParent)
|
|
{
|
|
bool bRet = false;
|
|
|
|
// choose script dialog
|
|
OUString aScriptURL = SfxApplication::ChooseScript(pDialogParent);
|
|
|
|
// the script selector dialog returns a valid script URL
|
|
if ( !aScriptURL.isEmpty() )
|
|
{
|
|
SetMacroPath( aScriptURL );
|
|
bRet = true;
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
void SwFieldMgr::SetMacroPath(const OUString& rPath)
|
|
{
|
|
m_sMacroPath = rPath;
|
|
m_sMacroName = rPath;
|
|
|
|
// try to set sMacroName member variable by parsing the macro path
|
|
// using the new URI parsing services
|
|
|
|
const Reference< XComponentContext >& xContext =
|
|
::comphelper::getProcessComponentContext();
|
|
|
|
Reference< uri::XUriReferenceFactory >
|
|
xFactory = uri::UriReferenceFactory::create( xContext );
|
|
|
|
Reference< uri::XVndSunStarScriptUrl >
|
|
xUrl( xFactory->parse( m_sMacroPath ), UNO_QUERY );
|
|
|
|
if ( xUrl.is() )
|
|
{
|
|
m_sMacroName = xUrl->getName();
|
|
}
|
|
}
|
|
|
|
sal_uInt32 SwFieldMgr::GetDefaultFormat(SwFieldTypesEnum nTypeId, bool bIsText, SvNumberFormatter* pFormatter)
|
|
{
|
|
SvNumFormatType nDefFormat;
|
|
|
|
switch (nTypeId)
|
|
{
|
|
case SwFieldTypesEnum::Time:
|
|
case SwFieldTypesEnum::Date:
|
|
{
|
|
nDefFormat = (nTypeId == SwFieldTypesEnum::Date) ? SvNumFormatType::DATE : SvNumFormatType::TIME;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
if (bIsText)
|
|
{
|
|
nDefFormat = SvNumFormatType::TEXT;
|
|
}
|
|
else
|
|
{
|
|
nDefFormat = SvNumFormatType::ALL;
|
|
}
|
|
break;
|
|
}
|
|
|
|
return pFormatter->GetStandardFormat(nDefFormat, GetCurrLanguage());
|
|
}
|
|
|
|
Reference<XNumberingTypeInfo> const & SwFieldMgr::GetNumberingInfo() const
|
|
{
|
|
if(!m_xNumberingInfo.is())
|
|
{
|
|
const Reference<XComponentContext>& xContext( ::comphelper::getProcessComponentContext() );
|
|
Reference<XDefaultNumberingProvider> xDefNum = text::DefaultNumberingProvider::create(xContext);
|
|
const_cast<SwFieldMgr*>(this)->m_xNumberingInfo.set(xDefNum, UNO_QUERY);
|
|
}
|
|
return m_xNumberingInfo;
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|