/* -*- 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace ::com::sun::star; namespace { /// Implements getCommandValues(".uno:TextFormFields"). /// /// Parameters: /// /// - type: e.g. ODF_UNHANDLED /// - commandPrefix: field command prefix to not return all fieldmarks void GetTextFormFields(tools::JsonWriter& rJsonWriter, SwDocShell* pDocShell, const std::map& rArguments) { OUString aType; OUString aCommandPrefix; { auto it = rArguments.find("type"); if (it != rArguments.end()) { aType = it->second; } it = rArguments.find("commandPrefix"); if (it != rArguments.end()) { aCommandPrefix = it->second; } } SwDoc* pDoc = pDocShell->GetDoc(); IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess(); tools::ScopedJsonWriterArray aFields = rJsonWriter.startArray("fields"); for (auto it = pMarkAccess->getFieldmarksBegin(); it != pMarkAccess->getFieldmarksEnd(); ++it) { auto pFieldmark = dynamic_cast(*it); assert(pFieldmark); if (pFieldmark->GetFieldname() != aType) { continue; } auto itParam = pFieldmark->GetParameters()->find(ODF_CODE_PARAM); if (itParam == pFieldmark->GetParameters()->end()) { continue; } OUString aCommand; itParam->second >>= aCommand; if (!aCommand.startsWith(aCommandPrefix)) { continue; } tools::ScopedJsonWriterStruct aField = rJsonWriter.startStruct(); rJsonWriter.put("type", aType); rJsonWriter.put("command", aCommand); } } /// Implements getCommandValues(".uno:TextFormField"). /// /// Parameters: /// /// - type: e.g. ODF_UNHANDLED /// - commandPrefix: field command prefix to not return all fieldmarks void GetTextFormField(tools::JsonWriter& rJsonWriter, SwDocShell* pDocShell, const std::map& rArguments) { OUString aType; OUString aCommandPrefix; auto it = rArguments.find("type"); if (it != rArguments.end()) { aType = it->second; } it = rArguments.find("commandPrefix"); if (it != rArguments.end()) { aCommandPrefix = it->second; } IDocumentMarkAccess& rIDMA = *pDocShell->GetDoc()->getIDocumentMarkAccess(); SwWrtShell* pWrtShell = pDocShell->GetWrtShell(); SwPosition& rCursor = *pWrtShell->GetCursor()->GetPoint(); sw::mark::IFieldmark* pFieldmark = rIDMA.getFieldmarkFor(rCursor); auto typeNode = rJsonWriter.startNode("field"); if (!pFieldmark) { return; } if (pFieldmark->GetFieldname() != aType) { return; } auto itParam = pFieldmark->GetParameters()->find(ODF_CODE_PARAM); if (itParam == pFieldmark->GetParameters()->end()) { return; } OUString aCommand; itParam->second >>= aCommand; if (!aCommand.startsWith(aCommandPrefix)) { return; } rJsonWriter.put("type", aType); rJsonWriter.put("command", aCommand); } /// Implements getCommandValues(".uno:SetDocumentProperties"). /// /// Parameters: /// /// - namePrefix: field name prefix to not return all user-defined properties void GetDocumentProperties(tools::JsonWriter& rJsonWriter, SwDocShell* pDocShell, const std::map& rArguments) { OUString aNamePrefix; auto it = rArguments.find("namePrefix"); if (it != rArguments.end()) { aNamePrefix = it->second; } uno::Reference xDPS(pDocShell->GetModel(), uno::UNO_QUERY); uno::Reference xDP = xDPS->getDocumentProperties(); uno::Reference xUDP(xDP->getUserDefinedProperties(), uno::UNO_QUERY); auto aUDPs = comphelper::sequenceToContainer>( xUDP->getPropertyValues()); tools::ScopedJsonWriterArray aProperties = rJsonWriter.startArray("userDefinedProperties"); for (const auto& rUDP : aUDPs) { if (!rUDP.Name.startsWith(aNamePrefix)) { continue; } if (rUDP.Value.getValueTypeClass() != uno::TypeClass_STRING) { continue; } OUString aValue; rUDP.Value >>= aValue; tools::ScopedJsonWriterStruct aProperty = rJsonWriter.startStruct(); rJsonWriter.put("name", rUDP.Name); rJsonWriter.put("type", "string"); rJsonWriter.put("value", aValue); } } /// Implements getCommandValues(".uno:Bookmarks"). /// /// Parameters: /// /// - namePrefix: bookmark name prefix to not return all bookmarks void GetBookmarks(tools::JsonWriter& rJsonWriter, SwDocShell* pDocShell, const std::map& rArguments) { OUString aNamePrefix; { auto it = rArguments.find("namePrefix"); if (it != rArguments.end()) { aNamePrefix = it->second; } } IDocumentMarkAccess& rIDMA = *pDocShell->GetDoc()->getIDocumentMarkAccess(); tools::ScopedJsonWriterArray aBookmarks = rJsonWriter.startArray("bookmarks"); for (auto it = rIDMA.getBookmarksBegin(); it != rIDMA.getBookmarksEnd(); ++it) { sw::mark::IMark* pMark = *it; if (!pMark->GetName().startsWith(aNamePrefix)) { continue; } tools::ScopedJsonWriterStruct aProperty = rJsonWriter.startStruct(); rJsonWriter.put("name", pMark->GetName()); } } /// Implements getCommandValues(".uno:Bookmark"). /// /// Parameters: /// /// - namePrefix: bookmark name prefix to not return all bookmarks void GetBookmark(tools::JsonWriter& rJsonWriter, SwDocShell* pDocShell, const std::map& rArguments) { OUString aNamePrefix; { auto it = rArguments.find("namePrefix"); if (it != rArguments.end()) { aNamePrefix = it->second; } } IDocumentMarkAccess& rIDMA = *pDocShell->GetDoc()->getIDocumentMarkAccess(); SwWrtShell* pWrtShell = pDocShell->GetWrtShell(); SwPosition& rCursor = *pWrtShell->GetCursor()->GetPoint(); sw::mark::IMark* pBookmark = rIDMA.getOneInnermostBookmarkFor(rCursor); tools::ScopedJsonWriterNode aBookmark = rJsonWriter.startNode("bookmark"); if (!pBookmark) { return; } if (!pBookmark->GetName().startsWith(aNamePrefix)) { return; } rJsonWriter.put("name", pBookmark->GetName()); } /// Implements getCommandValues(".uno:Fields"). /// /// Parameters: /// /// - typeName: field type condition to not return all fields /// - namePrefix: field name prefix to not return all fields void GetFields(tools::JsonWriter& rJsonWriter, SwDocShell* pDocShell, const std::map& rArguments) { OUString aTypeName; { auto it = rArguments.find("typeName"); if (it != rArguments.end()) { aTypeName = it->second; } } // See SwFieldTypeFromString(). if (aTypeName != "SetRef") { return; } OUString aNamePrefix; { auto it = rArguments.find("namePrefix"); if (it != rArguments.end()) { aNamePrefix = it->second; } } SwDoc* pDoc = pDocShell->GetDoc(); tools::ScopedJsonWriterArray aBookmarks = rJsonWriter.startArray("setRefs"); std::vector aRefMarks; for (sal_uInt16 i = 0; i < pDoc->GetRefMarks(); ++i) { aRefMarks.push_back(pDoc->GetRefMark(i)); } // Sort the refmarks based on their start position. std::sort(aRefMarks.begin(), aRefMarks.end(), [](const SwFormatRefMark* pMark1, const SwFormatRefMark* pMark2) -> bool { const SwTextRefMark* pTextRefMark1 = pMark1->GetTextRefMark(); const SwTextRefMark* pTextRefMark2 = pMark2->GetTextRefMark(); SwPosition aPos1(pTextRefMark1->GetTextNode(), pTextRefMark1->GetStart()); SwPosition aPos2(pTextRefMark2->GetTextNode(), pTextRefMark2->GetStart()); return aPos1 < aPos2; }); for (const auto& pRefMark : aRefMarks) { if (!pRefMark->GetRefName().startsWith(aNamePrefix)) { continue; } tools::ScopedJsonWriterStruct aProperty = rJsonWriter.startStruct(); rJsonWriter.put("name", pRefMark->GetRefName()); } } /// Implements getCommandValues(".uno:Field"). /// /// Parameters: /// /// - typeName: field type condition to not return all fields /// - namePrefix: field name prefix to not return all fields void GetField(tools::JsonWriter& rJsonWriter, SwDocShell* pDocShell, const std::map& rArguments) { OUString aTypeName; { auto it = rArguments.find("typeName"); if (it != rArguments.end()) { aTypeName = it->second; } } // See SwFieldTypeFromString(). if (aTypeName != "SetRef") { return; } OUString aNamePrefix; { auto it = rArguments.find("namePrefix"); if (it != rArguments.end()) { aNamePrefix = it->second; } } SwWrtShell* pWrtShell = pDocShell->GetWrtShell(); SwPosition& rCursor = *pWrtShell->GetCursor()->GetPoint(); SwTextNode* pTextNode = rCursor.GetNode().GetTextNode(); std::vector aAttrs = pTextNode->GetTextAttrsAt(rCursor.GetContentIndex(), RES_TXTATR_REFMARK); tools::ScopedJsonWriterNode aRefmark = rJsonWriter.startNode("setRef"); if (aAttrs.empty()) { return; } const SwFormatRefMark& rRefmark = aAttrs[0]->GetRefMark(); if (!rRefmark.GetRefName().startsWith(aNamePrefix)) { return; } rJsonWriter.put("name", rRefmark.GetRefName()); } /// Implements getCommandValues(".uno:Sections"). /// /// Parameters: /// /// - namePrefix: field name prefix to not return all sections void GetSections(tools::JsonWriter& rJsonWriter, SwDocShell* pDocShell, const std::map& rArguments) { OUString aNamePrefix; { auto it = rArguments.find("namePrefix"); if (it != rArguments.end()) { aNamePrefix = it->second; } } SwDoc* pDoc = pDocShell->GetDoc(); tools::ScopedJsonWriterArray aBookmarks = rJsonWriter.startArray("sections"); for (const auto& pSection : pDoc->GetSections()) { if (!pSection->GetName().startsWith(aNamePrefix)) { continue; } tools::ScopedJsonWriterStruct aProperty = rJsonWriter.startStruct(); rJsonWriter.put("name", pSection->GetName()); } } } bool SwXTextDocument::supportsCommand(std::u16string_view rCommand) { static const std::initializer_list vForward = { u"TextFormFields", u"TextFormField", u"SetDocumentProperties", u"Bookmarks", u"Fields", u"Sections", u"Bookmark", u"Field" }; return std::find(vForward.begin(), vForward.end(), rCommand) != vForward.end(); } void SwXTextDocument::getCommandValues(tools::JsonWriter& rJsonWriter, std::string_view rCommand) { std::map aMap; static constexpr OStringLiteral aTextFormFields(".uno:TextFormFields"); static constexpr OStringLiteral aTextFormField(".uno:TextFormField"); static constexpr OStringLiteral aSetDocumentProperties(".uno:SetDocumentProperties"); static constexpr OStringLiteral aBookmarks(".uno:Bookmarks"); static constexpr OStringLiteral aFields(".uno:Fields"); static constexpr OStringLiteral aSections(".uno:Sections"); static constexpr OStringLiteral aBookmark(".uno:Bookmark"); static constexpr OStringLiteral aField(".uno:Field"); INetURLObject aParser(OUString::fromUtf8(rCommand)); OUString aArguments = aParser.GetParam(); sal_Int32 nParamIndex = 0; do { std::u16string_view aParam = o3tl::getToken(aArguments, 0, '&', nParamIndex); sal_Int32 nIndex = 0; OUString aKey; OUString aValue; do { std::u16string_view aToken = o3tl::getToken(aParam, 0, '=', nIndex); if (aKey.isEmpty()) aKey = aToken; else aValue = aToken; } while (nIndex >= 0); OUString aDecodedValue = INetURLObject::decode(aValue, INetURLObject::DecodeMechanism::WithCharset); aMap[aKey] = aDecodedValue; } while (nParamIndex >= 0); if (o3tl::starts_with(rCommand, aTextFormFields)) { GetTextFormFields(rJsonWriter, m_pDocShell, aMap); } if (o3tl::starts_with(rCommand, aTextFormField)) { GetTextFormField(rJsonWriter, m_pDocShell, aMap); } else if (o3tl::starts_with(rCommand, aSetDocumentProperties)) { GetDocumentProperties(rJsonWriter, m_pDocShell, aMap); } else if (o3tl::starts_with(rCommand, aBookmarks)) { GetBookmarks(rJsonWriter, m_pDocShell, aMap); } else if (o3tl::starts_with(rCommand, aFields)) { GetFields(rJsonWriter, m_pDocShell, aMap); } else if (o3tl::starts_with(rCommand, aSections)) { GetSections(rJsonWriter, m_pDocShell, aMap); } else if (o3tl::starts_with(rCommand, aBookmark)) { GetBookmark(rJsonWriter, m_pDocShell, aMap); } else if (o3tl::starts_with(rCommand, aField)) { GetField(rJsonWriter, m_pDocShell, aMap); } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */