23#include <osl/diagnose.h>
29#include <com/sun/star/frame/XModel.hpp>
30#include <com/sun/star/lang/IllegalArgumentException.hpp>
37#include <unordered_map>
38#if OSL_DEBUG_LEVEL > 0
116constexpr OUStringLiteral
s_content =
u"content.xml";
117constexpr OUStringLiteral
s_styles =
u"styles.xml";
150 virtual css::uno::Reference< css::rdf::XMetadatable >
152 const css::beans::StringPair & i_rReference)
const
179 OUString
const& i_rStreamName, OUString
const& i_rIdref)
194 css::beans::StringPair
203 OUString & o_rStream, OUString & o_rIdref)
const = 0;
206 const OUString & i_rIdref)
const = 0;
218 XmlIdRegistryDocument();
220 virtual ~XmlIdRegistryDocument()
override;
222 virtual void RegisterMetadatableAndCreateID(Metadatable& i_xObject)
override;
224 virtual bool TryRegisterMetadatable(Metadatable& i_xObject,
225 OUString
const& i_rStreamName, OUString
const& i_rIdref)
override;
227 virtual void UnregisterMetadatable(Metadatable
const&)
override;
229 virtual void RemoveXmlIdForElement(Metadatable
const&)
override;
233 void RegisterCopy(Metadatable
const& i_rSource, Metadatable & i_rCopy,
234 const bool i_bCopyPrecedesSource);
237 static std::shared_ptr<MetadatableUndo> CreateUndo(
238 Metadatable
const& i_rObject);
241 void JoinMetadatables(Metadatable & i_rMerged, Metadatable
const& i_rOther);
244 virtual bool LookupXmlId(
const Metadatable& i_xObject,
245 OUString & o_rStream, OUString & o_rIdref)
const override;
249 virtual Metadatable* LookupElement(
const OUString & i_rStreamName,
250 const OUString & i_rIdref)
const override;
252 struct XmlIdRegistry_Impl;
253 ::std::unique_ptr<XmlIdRegistry_Impl>
m_pImpl;
272 OSL_ENSURE(m_pReg,
"no m_pReg in MetadatableUndo ?");
276 virtual bool IsInUndo()
const override {
return true; }
278 virtual css::uno::Reference< css::rdf::XMetadatable >
MakeUnoObject()
override
279 { OSL_FAIL(
"MetadatableUndo::MakeUnoObject");
throw; }
296 assert(m_pReg &&
"no m_pReg in MetadatableClipboard ?");
300 virtual bool IsInUndo()
const override {
return false; }
302 virtual css::uno::Reference< css::rdf::XMetadatable >
MakeUnoObject()
override
303 { OSL_FAIL(
"MetadatableClipboard::MakeUnoObject");
throw; }
311class XmlIdRegistryClipboard :
public XmlIdRegistry
315 XmlIdRegistryClipboard();
317 virtual void RegisterMetadatableAndCreateID(Metadatable& i_xObject)
override;
319 virtual bool TryRegisterMetadatable(Metadatable& i_xObject,
320 OUString
const& i_rStreamName, OUString
const& i_rIdref)
override;
322 virtual void UnregisterMetadatable(Metadatable
const&)
override;
324 virtual void RemoveXmlIdForElement(Metadatable
const&)
override;
327 MetadatableClipboard & RegisterCopyClipboard(Metadatable & i_rCopy,
328 beans::StringPair
const & i_rReference,
329 const bool i_isLatent);
332 MetadatableClipboard
const* SourceLink(Metadatable
const& i_rObject);
335 virtual bool LookupXmlId(
const Metadatable& i_xObject,
336 OUString & o_rStream, OUString & o_rIdref)
const override;
338 virtual Metadatable* LookupElement(
const OUString & i_rStreamName,
339 const OUString & i_rIdref)
const override;
342 static std::shared_ptr<MetadatableClipboard> CreateClipboard(
343 const bool i_isInContent);
345 struct XmlIdRegistry_Impl;
346 ::std::unique_ptr<XmlIdRegistry_Impl>
m_pImpl;
355 return i_DocIsClipboard
364css::uno::Reference< css::rdf::XMetadatable >
366 const beans::StringPair & i_rReference)
const
369 i_rReference.Second) );
382 return beans::StringPair(path, idref);
385 return beans::StringPair();
390template<
typename T >
392 std::unordered_map< OUString, T > & i_rXmlIdMap)
394 static bool bHack = (getenv(
"LIBO_ONEWAY_STABLE_ODF_EXPORT") !=
nullptr);
395 static const char prefix[] =
"id";
396 typename std::unordered_map< OUString, T >
397 ::const_iterator iter;
402 static sal_Int64 nIdCounter = SAL_CONST_INT64(4000000000);
405 id =
prefix + OUString::number(nIdCounter++);
406 iter = i_rXmlIdMap.find(
id);
408 while (iter != i_rXmlIdMap.end());
415 std::numeric_limits<unsigned int>::max()));
416 id =
prefix + OUString::number(
n);
417 iter = i_rXmlIdMap.find(
id);
419 while (iter != i_rXmlIdMap.end());
431typedef std::unordered_map< OUString,
437template<
typename T>
struct PtrHash
439 size_t operator() (T
const * i_pT)
const
441 return reinterpret_cast<size_t>(i_pT);
448typedef std::unordered_map<
const Metadatable*,
449 ::std::pair< OUString, OUString>, PtrHash<Metadatable> >
457 std::u16string_view i_rStream,
const OUString & i_rIdref);
460 OUString & o_rStream, OUString & o_rIdref)
const;
462 Metadatable*
LookupElement(std::u16string_view i_rStreamName,
463 const OUString & i_rIdref)
const;
466 std::u16string_view i_rStreamName,
467 const OUString & i_rIdref)
const;
470 std::u16string_view i_rStreamName,
471 const OUString & i_rIdref)
485 std::u16string_view i_rStream, Metadatable
const& i_rObject)
487 if (i_rIter != i_rXmlIdMap.end())
490 ? i_rIter->second.first : i_rIter->second.second );
491 rVector.erase(std::remove(rVector.begin(), rVector.end(), &
const_cast<Metadatable&
>(i_rObject)));
492 if (i_rIter->second.first.empty() && i_rIter->second.second.empty())
494 i_rXmlIdMap.erase(i_rIter);
502 std::u16string_view i_rStreamName,
503 const OUString & i_rIdref)
const
505 const XmlIdMap_t::const_iterator iter(
m_XmlIdMap.find(i_rIdref) );
508 OSL_ENSURE(!iter->second.first.empty() || !iter->second.second.empty(),
509 "null entry in m_XmlIdMap");
511 ? &iter->second.first
512 : &iter->second.second;
522 std::u16string_view i_rStreamName,
523 const OUString & i_rIdref)
const
527 throw lang::IllegalArgumentException(
"illegal XmlId",
nullptr, 0);
530 const XmlIdVector_t * pList( LookupElementVector(i_rStreamName, i_rIdref) );
533 const XmlIdVector_t::const_iterator iter(
534 ::std::find_if(pList->begin(), pList->end(),
535 [](Metadatable* item)->bool {
536 return !(item->IsInUndo() || item->IsInClipboard());
538 if (iter != pList->end())
548 const Metadatable& i_rObject,
549 OUString & o_rStream, OUString & o_rIdref)
const
551 const XmlIdReverseMap_t::const_iterator iter(
552 m_XmlIdReverseMap.find(&i_rObject) );
553 if (iter != m_XmlIdReverseMap.end())
555 OSL_ENSURE(!iter->second.first.isEmpty(),
556 "null stream in m_XmlIdReverseMap");
557 OSL_ENSURE(!iter->second.second.isEmpty(),
558 "null id in m_XmlIdReverseMap");
559 o_rStream = iter->second.first;
560 o_rIdref = iter->second.second;
571 Metadatable & i_rObject,
572 std::u16string_view i_rStreamName,
const OUString & i_rIdref)
578 XmlIdVector_t * pList( LookupElementVector(i_rStreamName, i_rIdref) );
583 pList->push_back( &i_rObject );
591 if ( std::none_of(pList->begin(), pList->end(),
592 [](Metadatable* item)->bool {
593 return !(item->IsInUndo() || item->IsInClipboard());
596 pList->insert(pList->begin(), &i_rObject );
607 m_XmlIdMap.insert(::std::make_pair(i_rIdref, bContent
618XmlIdRegistryDocument::XmlIdRegistryDocument()
626 OSL_ENSURE(i_pObject,
"null in list ???");
627 if (!i_pObject)
return;
628 if (i_pObject->IsInClipboard())
632 OSL_ENSURE(
pLink,
"IsInClipboard, but no MetadatableClipboard ?");
635 pLink->OriginNoLongerInBusinessAnymore();
640XmlIdRegistryDocument::~XmlIdRegistryDocument()
643 for (
const auto& aXmlId :
m_pImpl->m_XmlIdMap) {
644 for (
auto aLink : aXmlId.second.first)
646 for (
auto aLink : aXmlId.second.second)
652XmlIdRegistryDocument::LookupXmlId(
653 const Metadatable& i_rObject,
654 OUString & o_rStream, OUString & o_rIdref)
const
656 return m_pImpl->LookupXmlId(i_rObject, o_rStream, o_rIdref);
660XmlIdRegistryDocument::LookupElement(
661 const OUString & i_rStreamName,
662 const OUString & i_rIdref)
const
664 return m_pImpl->LookupElement(i_rStreamName, i_rIdref);
668XmlIdRegistryDocument::TryRegisterMetadatable(Metadatable & i_rObject,
669 OUString
const& i_rStreamName, OUString
const& i_rIdref)
671 SAL_INFO(
"sfx",
"TryRegisterMetadatable: " << &i_rObject <<
" (" << i_rStreamName <<
"#" << i_rIdref <<
")");
673 OSL_ENSURE(!
dynamic_cast<MetadatableUndo*
>(&i_rObject),
674 "TryRegisterMetadatable called for MetadatableUndo?");
675 OSL_ENSURE(!
dynamic_cast<MetadatableClipboard*
>(&i_rObject),
676 "TryRegisterMetadatable called for MetadatableClipboard?");
680 throw lang::IllegalArgumentException(
"illegal XmlId",
nullptr, 0);
682 if (i_rObject.IsInContent()
686 throw lang::IllegalArgumentException(
"illegal XmlId: wrong stream",
nullptr, 0);
691 m_pImpl->LookupXmlId(i_rObject, old_path, old_idref);
692 if (old_path == i_rStreamName && old_idref == i_rIdref)
694 return (
m_pImpl->LookupElement(old_path, old_idref) == &i_rObject);
696 XmlIdMap_t::iterator old_id(
m_pImpl->m_XmlIdMap.end() );
697 if (!old_idref.isEmpty())
699 old_id =
m_pImpl->m_XmlIdMap.find(old_idref);
700 OSL_ENSURE(old_id !=
m_pImpl->m_XmlIdMap.end(),
"old id not found");
702 if (
m_pImpl->TryInsertMetadatable(i_rObject, i_rStreamName, i_rIdref))
705 m_pImpl->m_XmlIdReverseMap[&i_rObject] =
706 ::std::make_pair(i_rStreamName, i_rIdref);
716XmlIdRegistryDocument::RegisterMetadatableAndCreateID(Metadatable & i_rObject)
718 SAL_INFO(
"sfx",
"RegisterMetadatableAndCreateID: " << &i_rObject);
720 OSL_ENSURE(!
dynamic_cast<MetadatableUndo*
>(&i_rObject),
721 "RegisterMetadatableAndCreateID called for MetadatableUndo?");
722 OSL_ENSURE(!
dynamic_cast<MetadatableClipboard*
>(&i_rObject),
723 "RegisterMetadatableAndCreateID called for MetadatableClipboard?");
725 const bool isInContent( i_rObject.IsInContent() );
731 m_pImpl->LookupXmlId(i_rObject, old_path, old_idref);
733 XmlIdMap_t::iterator old_id(
m_pImpl->m_XmlIdMap.end() );
734 if (!old_idref.isEmpty())
736 old_id =
m_pImpl->m_XmlIdMap.find(old_idref);
737 OSL_ENSURE(old_id !=
m_pImpl->m_XmlIdMap.end(),
"old id not found");
738 if (
m_pImpl->LookupElement(old_path, old_idref) == &i_rObject)
751 OSL_ENSURE(
m_pImpl->m_XmlIdMap.find(
id) ==
m_pImpl->m_XmlIdMap.end(),
752 "created id is in use");
753 m_pImpl->m_XmlIdMap.insert(::std::make_pair(
id, isInContent
756 m_pImpl->m_XmlIdReverseMap[&i_rObject] = ::std::make_pair(stream,
id);
759void XmlIdRegistryDocument::UnregisterMetadatable(
const Metadatable& i_rObject)
761 SAL_INFO(
"sfx",
"UnregisterMetadatable: " << &i_rObject);
765 if (!
m_pImpl->LookupXmlId(i_rObject, path, idref))
767 OSL_FAIL(
"unregister: no xml id?");
770 const XmlIdMap_t::iterator iter(
m_pImpl->m_XmlIdMap.find(idref) );
771 if (iter !=
m_pImpl->m_XmlIdMap.end())
777void XmlIdRegistryDocument::RemoveXmlIdForElement(
const Metadatable& i_rObject)
779 SAL_INFO(
"sfx",
"RemoveXmlIdForElement: " << &i_rObject);
781 const XmlIdReverseMap_t::iterator iter(
782 m_pImpl->m_XmlIdReverseMap.find(&i_rObject) );
783 if (iter !=
m_pImpl->m_XmlIdReverseMap.end())
785 OSL_ENSURE(!iter->second.second.isEmpty(),
786 "null id in m_XmlIdReverseMap");
787 m_pImpl->m_XmlIdReverseMap.erase(iter);
792void XmlIdRegistryDocument::RegisterCopy(Metadatable
const& i_rSource,
793 Metadatable & i_rCopy,
const bool i_bCopyPrecedesSource)
795 SAL_INFO(
"sfx",
"RegisterCopy: " << &i_rSource <<
" -> " << &i_rCopy <<
" (" << i_bCopyPrecedesSource <<
")");
800 OSL_ENSURE(i_rSource.IsInUndo() || i_rCopy.IsInUndo() ||
801 (i_rSource.IsInContent() == i_rCopy.IsInContent()),
802 "RegisterCopy: not in same stream?");
806 if (!
m_pImpl->LookupXmlId( i_rSource, path, idref ))
808 OSL_FAIL(
"no xml id?");
812 OSL_ENSURE( ::std::find( pList->begin(), pList->end(), &i_rCopy )
813 == pList->end(),
"copy already registered???");
814 XmlIdVector_t::iterator srcpos(
815 ::std::find( pList->begin(), pList->end(), &i_rSource ) );
816 OSL_ENSURE(srcpos != pList->end(),
"source not in list???");
817 if (srcpos == pList->end())
821 if (i_bCopyPrecedesSource)
823 pList->insert( srcpos, &i_rCopy );
828 pList->insert( ++srcpos, &i_rCopy );
830 m_pImpl->m_XmlIdReverseMap.insert(::std::make_pair(&i_rCopy,
831 ::std::make_pair(path, idref)));
834std::shared_ptr<MetadatableUndo>
835XmlIdRegistryDocument::CreateUndo(Metadatable
const& i_rObject)
837 SAL_INFO(
"sfx",
"CreateUndo: " << &i_rObject);
839 return std::make_shared<MetadatableUndo>(
840 i_rObject.IsInContent() );
861XmlIdRegistryDocument::JoinMetadatables(
862 Metadatable & i_rMerged, Metadatable
const & i_rOther)
864 SAL_INFO(
"sfx",
"JoinMetadatables: " << &i_rMerged <<
" <- " << &i_rOther);
869 if (
m_pImpl->LookupXmlId(i_rMerged, path, idref))
871 mergedOwnsRef = (
m_pImpl->LookupElement(path, idref) == &i_rMerged);
875 OSL_FAIL(
"JoinMetadatables: no xmlid?");
880 i_rMerged.RemoveMetadataReference();
881 i_rMerged.RegisterAsCopyOf(i_rOther,
true);
896 RMapEntry(OUString i_aStream,
898 std::shared_ptr<MetadatableClipboard> i_pLink
899 = std::shared_ptr<MetadatableClipboard>())
905 std::shared_ptr<MetadatableClipboard>
m_xLink;
911typedef std::unordered_map<
const Metadatable*,
913 PtrHash<Metadatable> >
917typedef std::unordered_map< OUString,
918 ::std::pair< Metadatable*, Metadatable* > >
925 bool TryInsertMetadatable(Metadatable& i_xObject,
926 std::u16string_view i_rStream,
const OUString & i_rIdref);
928 bool LookupXmlId(
const Metadatable& i_xObject,
929 OUString & o_rStream, OUString & o_rIdref,
932 Metadatable* LookupElement(std::u16string_view i_rStreamName,
933 const OUString & i_rIdref)
const;
935 Metadatable*
const* LookupEntry(std::u16string_view i_rStreamName,
936 const OUString & i_rIdref)
const;
945 ClipboardXmlIdMap_t::iterator
const& i_rIter,
946 std::u16string_view i_rStream, Metadatable
const& i_rObject)
948 if (i_rIter == i_rXmlIdMap.end())
952 ? i_rIter->second.first : i_rIter->second.second;
953 if (rMeta == &i_rObject)
957 if (!i_rIter->second.first && !i_rIter->second.second)
959 i_rXmlIdMap.erase(i_rIter);
966 std::u16string_view i_rStreamName,
967 const OUString & i_rIdref)
const
971 throw lang::IllegalArgumentException(
"illegal XmlId",
nullptr, 0);
974 const ClipboardXmlIdMap_t::const_iterator iter( m_XmlIdMap.find(i_rIdref) );
975 if (iter != m_XmlIdMap.end())
977 OSL_ENSURE(iter->second.first || iter->second.second,
978 "null entry in m_XmlIdMap");
980 ? &iter->second.first
981 : &iter->second.second;
991 std::u16string_view i_rStreamName,
992 const OUString & i_rIdref)
const
994 Metadatable *
const * ppEntry = LookupEntry(i_rStreamName, i_rIdref);
995 return ppEntry ? *ppEntry :
nullptr;
1000 const Metadatable& i_rObject,
1001 OUString & o_rStream, OUString & o_rIdref,
1004 const ClipboardXmlIdReverseMap_t::const_iterator iter(
1005 m_XmlIdReverseMap.find(&i_rObject) );
1006 if (iter != m_XmlIdReverseMap.end())
1008 OSL_ENSURE(!iter->second.m_Stream.isEmpty(),
1009 "null stream in m_XmlIdReverseMap");
1010 OSL_ENSURE(!iter->second.m_XmlId.isEmpty(),
1011 "null id in m_XmlIdReverseMap");
1012 o_rStream = iter->second.m_Stream;
1013 o_rIdref = iter->second.m_XmlId;
1014 o_rpLink = iter->second.m_xLink.get();
1025 Metadatable & i_rObject,
1026 std::u16string_view i_rStreamName,
const OUString & i_rIdref)
1032 Metadatable ** ppEntry =
const_cast<Metadatable**
>(LookupEntry(i_rStreamName, i_rIdref));
1041 *ppEntry = &i_rObject;
1047 m_XmlIdMap.insert(::std::make_pair(i_rIdref, bContent
1048 ? ::std::make_pair( &i_rObject,
static_cast<Metadatable*
>(
nullptr) )
1049 : ::std::make_pair(
static_cast<Metadatable*
>(
nullptr), &i_rObject )));
1058XmlIdRegistryClipboard::XmlIdRegistryClipboard()
1064XmlIdRegistryClipboard::LookupXmlId(
1065 const Metadatable& i_rObject,
1066 OUString & o_rStream, OUString & o_rIdref)
const
1069 return m_pImpl->LookupXmlId(i_rObject, o_rStream, o_rIdref,
pLink);
1073XmlIdRegistryClipboard::LookupElement(
1074 const OUString & i_rStreamName,
1075 const OUString & i_rIdref)
const
1077 return m_pImpl->LookupElement(i_rStreamName, i_rIdref);
1081XmlIdRegistryClipboard::TryRegisterMetadatable(Metadatable & i_rObject,
1082 OUString
const& i_rStreamName, OUString
const& i_rIdref)
1084 SAL_INFO(
"sfx",
"TryRegisterMetadatable: " << &i_rObject <<
" (" << i_rStreamName <<
"#" << i_rIdref <<
")");
1086 OSL_ENSURE(!
dynamic_cast<MetadatableUndo*
>(&i_rObject),
1087 "TryRegisterMetadatable called for MetadatableUndo?");
1088 OSL_ENSURE(!
dynamic_cast<MetadatableClipboard*
>(&i_rObject),
1089 "TryRegisterMetadatable called for MetadatableClipboard?");
1093 throw lang::IllegalArgumentException(
"illegal XmlId",
nullptr, 0);
1095 if (i_rObject.IsInContent()
1099 throw lang::IllegalArgumentException(
"illegal XmlId: wrong stream",
nullptr, 0);
1104 const MetadatableClipboard *
pLink;
1105 m_pImpl->LookupXmlId(i_rObject, old_path, old_idref,
pLink);
1106 if (old_path == i_rStreamName && old_idref == i_rIdref)
1108 return (
m_pImpl->LookupElement(old_path, old_idref) == &i_rObject);
1110 ClipboardXmlIdMap_t::iterator old_id(
m_pImpl->m_XmlIdMap.end() );
1111 if (!old_idref.isEmpty())
1113 old_id =
m_pImpl->m_XmlIdMap.find(old_idref);
1114 OSL_ENSURE(old_id !=
m_pImpl->m_XmlIdMap.end(),
"old id not found");
1116 if (
m_pImpl->TryInsertMetadatable(i_rObject, i_rStreamName, i_rIdref))
1119 m_pImpl->m_XmlIdReverseMap[&i_rObject] =
1120 RMapEntry(i_rStreamName, i_rIdref);
1130XmlIdRegistryClipboard::RegisterMetadatableAndCreateID(Metadatable & i_rObject)
1132 SAL_INFO(
"sfx",
"RegisterMetadatableAndCreateID: " << &i_rObject);
1134 OSL_ENSURE(!
dynamic_cast<MetadatableUndo*
>(&i_rObject),
1135 "RegisterMetadatableAndCreateID called for MetadatableUndo?");
1136 OSL_ENSURE(!
dynamic_cast<MetadatableClipboard*
>(&i_rObject),
1137 "RegisterMetadatableAndCreateID called for MetadatableClipboard?");
1139 bool isInContent( i_rObject.IsInContent() );
1145 LookupXmlId(i_rObject, old_path, old_idref);
1146 if (!old_idref.isEmpty() &&
1147 (
m_pImpl->LookupElement(old_path, old_idref) == &i_rObject))
1154 OSL_ENSURE(
m_pImpl->m_XmlIdMap.find(
id) ==
m_pImpl->m_XmlIdMap.end(),
1155 "created id is in use");
1156 m_pImpl->m_XmlIdMap.insert(::std::make_pair(
id, isInContent
1157 ? ::std::make_pair( &i_rObject,
static_cast<Metadatable*
>(
nullptr) )
1158 : ::std::make_pair(
static_cast<Metadatable*
>(
nullptr), &i_rObject )));
1161 m_pImpl->m_XmlIdReverseMap[&i_rObject] = RMapEntry(stream,
id);
1164void XmlIdRegistryClipboard::UnregisterMetadatable(
const Metadatable& i_rObject)
1166 SAL_INFO(
"sfx",
"UnregisterMetadatable: " << &i_rObject);
1170 const MetadatableClipboard *
pLink;
1171 if (!
m_pImpl->LookupXmlId(i_rObject, path, idref,
pLink))
1173 OSL_FAIL(
"unregister: no xml id?");
1176 const ClipboardXmlIdMap_t::iterator iter(
m_pImpl->m_XmlIdMap.find(idref) );
1177 if (iter !=
m_pImpl->m_XmlIdMap.end())
1184void XmlIdRegistryClipboard::RemoveXmlIdForElement(
const Metadatable& i_rObject)
1186 SAL_INFO(
"sfx",
"RemoveXmlIdForElement: " << &i_rObject);
1188 ClipboardXmlIdReverseMap_t::iterator iter(
1189 m_pImpl->m_XmlIdReverseMap.find(&i_rObject) );
1190 if (iter !=
m_pImpl->m_XmlIdReverseMap.end())
1192 OSL_ENSURE(!iter->second.m_XmlId.isEmpty(),
1193 "null id in m_XmlIdReverseMap");
1194 m_pImpl->m_XmlIdReverseMap.erase(iter);
1199std::shared_ptr<MetadatableClipboard>
1200XmlIdRegistryClipboard::CreateClipboard(
const bool i_isInContent)
1202 SAL_INFO(
"sfx",
"CreateClipboard:");
1204 return std::make_shared<MetadatableClipboard>(
1208MetadatableClipboard &
1209XmlIdRegistryClipboard::RegisterCopyClipboard(Metadatable & i_rCopy,
1210 beans::StringPair
const & i_rReference,
1211 const bool i_isLatent)
1213 SAL_INFO(
"sfx",
"RegisterCopyClipboard: " << &i_rCopy
1214 <<
" -> (" << i_rReference.First <<
"#" << i_rReference.Second <<
") (" << i_isLatent <<
")");
1220 if (!
isValidXmlId(i_rReference.First, i_rReference.Second))
1222 throw lang::IllegalArgumentException(
"illegal XmlId",
nullptr, 0);
1228 const bool success(
m_pImpl->TryInsertMetadatable(i_rCopy,
1229 i_rReference.First, i_rReference.Second) );
1230 OSL_ENSURE(success,
"RegisterCopyClipboard: TryInsert failed?");
1232 const std::shared_ptr<MetadatableClipboard> xLink(
1234 m_pImpl->m_XmlIdReverseMap.insert(::std::make_pair(&i_rCopy,
1235 RMapEntry(i_rReference.First, i_rReference.Second, xLink)));
1239MetadatableClipboard
const*
1240XmlIdRegistryClipboard::SourceLink(Metadatable
const& i_rObject)
1244 const MetadatableClipboard *
pLink(
nullptr );
1253Metadatable::~Metadatable()
1255 RemoveMetadataReference();
1258void Metadatable::RemoveMetadataReference()
1264 m_pReg->UnregisterMetadatable( *
this );
1265 m_pReg->RemoveXmlIdForElement( *
this );
1269 catch (
const uno::Exception &)
1277Metadatable::GetMetadataReference()
const
1281 return m_pReg->GetXmlIdForElement(*
this);
1283 return beans::StringPair();
1286void Metadatable::SetMetadataReference(
const css::beans::StringPair & i_rReference)
1288 if (i_rReference.Second.isEmpty())
1290 RemoveMetadataReference();
1294 OUString streamName( i_rReference.First );
1295 if (streamName.isEmpty())
1301 XmlIdRegistry & rReg(
dynamic_cast<XmlIdRegistry&
>( GetRegistry() ) );
1302 if (!rReg.TryRegisterMetadatable(*
this, streamName, i_rReference.Second))
1304 throw lang::IllegalArgumentException(
1305 "Metadatable::SetMetadataReference: argument is invalid",
nullptr, 0);
1312void Metadatable::EnsureMetadataReference()
1314 XmlIdRegistry& rReg(
1315 m_pReg ? *m_pReg :
dynamic_cast<XmlIdRegistry&
>( GetRegistry() ) );
1316 rReg.RegisterMetadatableAndCreateID( *
this );
1322 return const_cast< Metadatable&
>( i_rObject ).GetRegistry();
1326Metadatable::RegisterAsCopyOf(Metadatable
const & i_rSource,
1327 const bool i_bCopyPrecedesSource)
1329 OSL_ENSURE(
typeid(*
this) ==
typeid(i_rSource)
1330 ||
typeid(i_rSource) ==
typeid(MetadatableUndo)
1331 ||
typeid(*
this) ==
typeid(MetadatableUndo)
1332 ||
typeid(i_rSource) ==
typeid(MetadatableClipboard)
1333 ||
typeid(*
this) ==
typeid(MetadatableClipboard),
1334 "RegisterAsCopyOf element with different class?");
1335 OSL_ENSURE(!m_pReg,
"RegisterAsCopyOf called on element with XmlId?");
1339 RemoveMetadataReference();
1344 if (i_rSource.m_pReg)
1346 XmlIdRegistry & rReg(
1347 dynamic_cast<XmlIdRegistry&
>( GetRegistry() ) );
1348 if (i_rSource.m_pReg == &rReg)
1350 OSL_ENSURE(!IsInClipboard(),
1351 "RegisterAsCopy: both in clipboard?");
1352 if (!IsInClipboard())
1354 XmlIdRegistryDocument & rRegDoc(
1355 dynamic_cast<XmlIdRegistryDocument&
>( rReg ) );
1356 rRegDoc.RegisterCopy(i_rSource, *
this,
1357 i_bCopyPrecedesSource);
1363 XmlIdRegistryDocument * pRegDoc(
1364 dynamic_cast<XmlIdRegistryDocument *
>(&rReg) );
1365 XmlIdRegistryClipboard * pRegClp(
1366 dynamic_cast<XmlIdRegistryClipboard*
>(&rReg) );
1370 beans::StringPair SourceRef(
1371 i_rSource.m_pReg->GetXmlIdForElement(i_rSource) );
1372 bool isLatent( SourceRef.Second.isEmpty() );
1373 XmlIdRegistryDocument * pSourceRegDoc(
1374 dynamic_cast<XmlIdRegistryDocument*
>(i_rSource.m_pReg) );
1375 OSL_ENSURE(pSourceRegDoc,
"RegisterAsCopyOf: 2 clipboards?");
1376 if (!pSourceRegDoc)
return;
1380 pSourceRegDoc->LookupXmlId(i_rSource,
1381 SourceRef.First, SourceRef.Second);
1383 Metadatable & rLink(
1384 pRegClp->RegisterCopyClipboard(*
this, SourceRef, isLatent));
1387 pSourceRegDoc->RegisterCopy(i_rSource, rLink,
1389 rLink.m_pReg = pSourceRegDoc;
1393 XmlIdRegistryClipboard * pSourceRegClp(
1394 dynamic_cast<XmlIdRegistryClipboard*
>(i_rSource.m_pReg) );
1395 OSL_ENSURE(pSourceRegClp,
1396 "RegisterAsCopyOf: 2 non-clipboards?");
1397 if (!pSourceRegClp)
return;
1398 const MetadatableClipboard *
pLink(
1399 pSourceRegClp->SourceLink(i_rSource) );
1408 bool srcInContent(
pLink->IsInContent() );
1409 bool tgtInContent( IsInContent() );
1410 if (srcInContent == tgtInContent)
1412 pRegDoc->RegisterCopy(*
pLink, *
this,
1421 OSL_FAIL(
"neither RegDoc nor RegClp cannot happen");
1425 catch (
const uno::Exception &)
1431std::shared_ptr<MetadatableUndo> Metadatable::CreateUndo()
const
1433 OSL_ENSURE(!IsInUndo(),
"CreateUndo called for object in undo?");
1434 OSL_ENSURE(!IsInClipboard(),
"CreateUndo called for object in clipboard?");
1437 if (!IsInClipboard() && !IsInUndo() && m_pReg)
1439 XmlIdRegistryDocument * pRegDoc(
1440 dynamic_cast<XmlIdRegistryDocument*
>( m_pReg ) );
1442 std::shared_ptr<MetadatableUndo> xUndo(
1443 sfx2::XmlIdRegistryDocument::CreateUndo(*
this) );
1444 pRegDoc->RegisterCopy(*
this, *xUndo,
false);
1445 xUndo->m_pReg = pRegDoc;
1449 catch (
const uno::Exception &)
1453 return std::shared_ptr<MetadatableUndo>();
1456std::shared_ptr<MetadatableUndo> Metadatable::CreateUndoForDelete()
1458 std::shared_ptr<MetadatableUndo>
const xUndo( CreateUndo() );
1459 RemoveMetadataReference();
1463void Metadatable::RestoreMetadata(
1464 std::shared_ptr<MetadatableUndo>
const& i_pUndo)
1466 OSL_ENSURE(!IsInUndo(),
"RestoreMetadata called for object in undo?");
1467 OSL_ENSURE(!IsInClipboard(),
1468 "RestoreMetadata called for object in clipboard?");
1469 if (IsInClipboard() || IsInUndo())
return;
1470 RemoveMetadataReference();
1473 RegisterAsCopyOf(*i_pUndo,
true);
1478Metadatable::JoinMetadatable(Metadatable
const & i_rOther,
1479 const bool i_isMergedEmpty,
const bool i_isOtherEmpty)
1481 OSL_ENSURE(!IsInUndo(),
"JoinMetadatables called for object in undo?");
1482 OSL_ENSURE(!IsInClipboard(),
1483 "JoinMetadatables called for object in clipboard?");
1484 if (IsInClipboard() || IsInUndo())
return;
1486 if (i_isOtherEmpty && !i_isMergedEmpty)
1491 if (i_isMergedEmpty && !i_isOtherEmpty)
1493 RemoveMetadataReference();
1494 RegisterAsCopyOf(i_rOther,
true);
1498 if (!i_rOther.m_pReg)
1505 RegisterAsCopyOf(i_rOther,
true);
1511 XmlIdRegistryDocument * pRegDoc(
1512 dynamic_cast<XmlIdRegistryDocument*
>( m_pReg ) );
1513 OSL_ENSURE(pRegDoc,
"JoinMetadatable: no pRegDoc?");
1516 pRegDoc->JoinMetadatables(*
this, i_rOther);
1519 catch (
const uno::Exception &)
1531 return getNamespace() + getLocalName();
1538 beans::StringPair mdref( getMetadataReference() );
1539 if (mdref.Second.isEmpty())
1541 ensureMetadataReference();
1542 mdref = getMetadataReference();
1544 return mdref.First +
"#" + mdref.Second;
1550 const uno::Reference< frame::XModel >
xModel( GetModel() );
1551 const uno::Reference< rdf::XURI > xDMA(
xModel, uno::UNO_QUERY_THROW );
1552 return xDMA->getStringValue();
1556beans::StringPair SAL_CALL
1561 Metadatable *
const pObject( GetCoreObject() );
1564 throw uno::RuntimeException(
1565 "MetadatableMixin: cannot get core object; not inserted?",
1568 return pObject->GetMetadataReference();
1573 const beans::StringPair & i_rReference)
1577 Metadatable *
const pObject( GetCoreObject() );
1580 throw uno::RuntimeException(
1581 "MetadatableMixin: cannot get core object; not inserted?",
1584 return pObject->SetMetadataReference(i_rReference);
1591 Metadatable *
const pObject( GetCoreObject() );
1594 throw uno::RuntimeException(
1595 "MetadatableMixin: cannot get core object; not inserted?",
1598 return pObject->EnsureMetadataReference();
interface for getElementByMetadataReference; for use by sfx2::DocumentMetadataAccess
handles registration of XMetadatable.
virtual bool TryRegisterMetadatable(Metadatable &i_xObject, OUString const &i_rStreamName, OUString const &i_rIdref)=0
try to register an ODF element at a given XML ID, or update its registration to a different XML ID.
virtual bool LookupXmlId(const Metadatable &i_xObject, OUString &o_rStream, OUString &o_rIdref) const =0
virtual css::uno::Reference< css::rdf::XMetadatable > GetElementByMetadataReference(const css::beans::StringPair &i_rReference) const override
get the ODF element with the given metadata reference.
virtual void RegisterMetadatableAndCreateID(Metadatable &i_xObject)=0
register an ODF element at a newly generated, unique metadata reference.
css::beans::StringPair GetXmlIdForElement(Metadatable const &) const
get the metadata reference for the given element.
virtual void RemoveXmlIdForElement(Metadatable const &)=0
remove the metadata reference for the given element.
virtual void UnregisterMetadatable(Metadatable const &)=0
unregister an ODF element.
virtual Metadatable * LookupElement(const OUString &i_rStreamName, const OUString &i_rIdref) const =0
#define TOOLS_WARN_EXCEPTION(area, stream)
Reference< XOutputStream > stream
EmbeddedObjectRef * pObject
#define SAL_INFO(area, stream)
unsigned int uniform_uint_distribution(unsigned int a, unsigned int b)
static OUString create_id(const std::unordered_map< OUString, T > &i_rXmlIdMap)
generate unique xml:id
constexpr OUStringLiteral s_styles
constexpr OUStringLiteral s_content
::std::vector< Metadatable * > XmlIdVector_t
element list
static void rmIter(XmlIdMap_t &i_rXmlIdMap, XmlIdMap_t::iterator const &i_rIter, std::u16string_view i_rStream, Metadatable const &i_rObject)
std::unordered_map< OUString, ::std::pair< Metadatable *, Metadatable * > > ClipboardXmlIdMap_t
Idref -> (content.xml element, styles.xml element)
bool isValidXmlId(std::u16string_view i_rStreamName, std::u16string_view i_rIdref)
std::unordered_map< const Metadatable *, ::std::pair< OUString, OUString >, PtrHash< Metadatable > > XmlIdReverseMap_t
element -> (stream name, idref)
static void removeLink(Metadatable *i_pObject)
static bool isStylesFile(std::u16string_view i_rPath)
::sfx2::IXmlIdRegistry * createXmlIdRegistry(const bool i_DocIsClipboard)
create a sfx2::XmlIdRegistryDocument or a sfx2::XmlIdRegistryClipboard
static const ::sfx2::IXmlIdRegistry & GetRegistryConst(Metadatable const &i_rObject)
std::unordered_map< const Metadatable *, struct RMapEntry, PtrHash< Metadatable > > ClipboardXmlIdReverseMap_t
element -> (stream name, idref, source)
std::unordered_map< OUString, ::std::pair< XmlIdVector_t, XmlIdVector_t > > XmlIdMap_t
Idref -> (content.xml element list, styles.xml element list)
static bool isContentFile(std::u16string_view i_rPath)
Metadatable * LookupElement(std::u16string_view i_rStreamName, const OUString &i_rIdref) const
ClipboardXmlIdReverseMap_t m_XmlIdReverseMap
Metadatable *const * LookupEntry(std::u16string_view i_rStreamName, const OUString &i_rIdref) const
bool TryInsertMetadatable(Metadatable &i_xObject, std::u16string_view i_rStream, const OUString &i_rIdref)
ClipboardXmlIdMap_t m_XmlIdMap
bool LookupXmlId(const Metadatable &i_xObject, OUString &o_rStream, OUString &o_rIdref, MetadatableClipboard const *&o_rpLink) const
Metadatable * LookupElement(std::u16string_view i_rStreamName, const OUString &i_rIdref) const
XmlIdReverseMap_t m_XmlIdReverseMap
bool TryInsertMetadatable(Metadatable &i_xObject, std::u16string_view i_rStream, const OUString &i_rIdref)
XmlIdVector_t * LookupElementVector(std::u16string_view i_rStreamName, const OUString &i_rIdref)
const XmlIdVector_t * LookupElementVector(std::u16string_view i_rStreamName, const OUString &i_rIdref) const
bool LookupXmlId(const Metadatable &i_xObject, OUString &o_rStream, OUString &o_rIdref) const
Reference< XModel > xModel