1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <IDocumentSettingAccess.hxx>
22 #include <IDocumentFieldsAccess.hxx>
23 #include <IDocumentLayoutAccess.hxx>
24 #include <contentindex.hxx>
26 #include <swtable.hxx>
27 #include <swddetbl.hxx>
30 #include <ndindex.hxx>
31 #include <fldupde.hxx>
32 #include <swtblfmt.hxx>
33 #include <fieldhint.hxx>
34 #include <osl/diagnose.h>
37 /// Ctor moves all lines/boxes from a SwTable into itself.
38 /// Afterwards the SwTable is empty and must be deleted.
39 SwDDETable::SwDDETable( SwTable
& rTable
, SwDDEFieldType
* pDDEType
, bool bUpdate
)
40 : SwTable(rTable
), m_aDepends(*this), m_pDDEType(pDDEType
)
42 m_aDepends
.StartListening(m_pDDEType
);
43 // copy the table data
44 m_TabSortContentBoxes
.insert(rTable
.GetTabSortBoxes());
45 rTable
.GetTabSortBoxes().clear();
47 m_aLines
.insert( m_aLines
.begin(),
48 rTable
.GetTabLines().begin(), rTable
.GetTabLines().end() ); // move lines
49 rTable
.GetTabLines().clear();
51 if( !m_aLines
.empty() )
53 const SwNode
& rNd
= *GetTabSortBoxes()[0]->GetSttNd();
54 if( rNd
.GetNodes().IsDocNodes() )
56 pDDEType
->IncRefCnt();
58 // update box content only if update flag is set (false in import)
65 SwDDETable::~SwDDETable()
67 SwDoc
* pDoc
= GetFrameFormat()->GetDoc();
68 if (!pDoc
->IsInDtor() && !m_aLines
.empty())
71 if (m_pTableNode
->GetNodes().IsDocNodes())
73 m_pDDEType
->DecRefCnt();
77 // If it is the last dependent of the "deleted field" than delete it finally
78 if( m_pDDEType
->IsDeleted() && m_pDDEType
->HasOnlyOneListener() )
80 m_aDepends
.EndListeningAll();
86 void SwDDETable::SwClientNotify(const SwModify
& rModify
, const SfxHint
& rHint
)
88 if (rHint
.GetId() == SfxHintId::SwLegacyModify
)
90 SwTable::SwClientNotify(rModify
, rHint
);
92 else if (rHint
.GetId() == SfxHintId::SwField
)
94 auto pFieldHint
= static_cast<const SwFieldHint
*>(&rHint
);
95 pFieldHint
->m_pPaM
->DeleteMark(); // TODO: this is really hackish
96 // replace DDETable by real table
99 else if(const auto pLinkAnchorHint
= dynamic_cast<const sw::LinkAnchorSearchHint
*>(&rHint
))
101 if(pLinkAnchorHint
->m_rpFoundNode
)
103 const auto pNd
= GetTabSortBoxes()[0]->GetSttNd();
104 if( pNd
&& &pLinkAnchorHint
->m_rNodes
== &pNd
->GetNodes() )
105 pLinkAnchorHint
->m_rpFoundNode
= pNd
;
107 else if(const sw::InRangeSearchHint
* pInRangeHint
= dynamic_cast<const sw::InRangeSearchHint
*>(&rHint
))
109 if(pInRangeHint
->m_rIsInRange
)
111 const SwTableNode
* pTableNd
= GetTabSortBoxes()[0]->GetSttNd()->FindTableNode();
112 if( pTableNd
->GetNodes().IsDocNodes() &&
113 pInRangeHint
->m_nSttNd
< pTableNd
->EndOfSectionIndex() &&
114 pInRangeHint
->m_nEndNd
> pTableNd
->GetIndex() )
115 pInRangeHint
->m_rIsInRange
= true;
116 } else if (const auto pGatherDdeTablesHint
= dynamic_cast<const sw::GatherDdeTablesHint
*>(&rHint
))
118 pGatherDdeTablesHint
->m_rvTables
.push_back(this);
120 else if (auto pModifyChangedHint
= dynamic_cast<const sw::ModifyChangedHint
*>(&rHint
))
122 if(m_pDDEType
== &rModify
)
123 m_pDDEType
= const_cast<SwDDEFieldType
*>(static_cast<const SwDDEFieldType
*>(pModifyChangedHint
->m_pNew
));
127 void SwDDETable::ChangeContent()
129 OSL_ENSURE( GetFrameFormat(), "No FrameFormat" );
131 // Is this the correct NodesArray? (because of UNDO)
132 if( m_aLines
.empty() )
134 OSL_ENSURE( !GetTabSortBoxes().empty(), "Table without content?" );
135 if( !GetTabSortBoxes()[0]->GetSttNd()->GetNodes().IsDocNodes() )
139 OUString aExpand
= m_pDDEType
->GetExpansion().replaceAll("\r", "");
140 sal_Int32 nExpandTokenPos
= 0;
142 for( size_t n
= 0; n
< m_aLines
.size(); ++n
)
144 OUString aLine
= aExpand
.getToken( 0, '\n', nExpandTokenPos
);
145 sal_Int32 nLineTokenPos
= 0;
146 SwTableLine
* pLine
= m_aLines
[ n
];
147 for( size_t i
= 0; i
< pLine
->GetTabBoxes().size(); ++i
)
149 SwTableBox
* pBox
= pLine
->GetTabBoxes()[ i
];
150 OSL_ENSURE( pBox
->GetSttIdx(), "no content box" );
151 SwNodeIndex
aNdIdx( *pBox
->GetSttNd(), 1 );
152 SwTextNode
* pTextNode
= aNdIdx
.GetNode().GetTextNode();
153 OSL_ENSURE( pTextNode
, "No Node" );
154 SwContentIndex
aCntIdx( pTextNode
, 0 );
155 pTextNode
->EraseText( aCntIdx
);
156 pTextNode
->InsertText( aLine
.getToken( 0, '\t', nLineTokenPos
), aCntIdx
);
158 SwTableBoxFormat
* pBoxFormat
= static_cast<SwTableBoxFormat
*>(pBox
->GetFrameFormat());
159 pBoxFormat
->LockModify();
160 pBoxFormat
->ResetFormatAttr( RES_BOXATR_VALUE
);
161 pBoxFormat
->UnlockModify();
165 const IDocumentSettingAccess
& rIDSA
= GetFrameFormat()->getIDocumentSettingAccess();
166 SwDoc
* pDoc
= GetFrameFormat()->GetDoc();
167 if( AUTOUPD_FIELD_AND_CHARTS
== rIDSA
.getFieldUpdateFlags(true) )
168 pDoc
->getIDocumentFieldsAccess().SetFieldsDirty( true, nullptr, SwNodeOffset(0) );
171 SwDDEFieldType
* SwDDETable::GetDDEFieldType()
176 void SwDDETable::NoDDETable()
179 OSL_ENSURE( GetFrameFormat(), "No FrameFormat" );
180 SwDoc
* pDoc
= GetFrameFormat()->GetDoc();
182 // Is this the correct NodesArray? (because of UNDO)
183 if( m_aLines
.empty() )
185 OSL_ENSURE( !GetTabSortBoxes().empty(), "Table without content?" );
186 SwNode
* pNd
= const_cast<SwNode
*>(static_cast<SwNode
const *>(GetTabSortBoxes()[0]->GetSttNd()));
187 if( !pNd
->GetNodes().IsDocNodes() )
190 SwTableNode
* pTableNd
= pNd
->FindTableNode();
191 OSL_ENSURE( pTableNd
, "Where is the table?");
193 std::unique_ptr
<SwTable
> pNewTable(new SwTable( *this ));
195 // copy the table data
196 pNewTable
->GetTabSortBoxes().insert( GetTabSortBoxes() ); // move content boxes
197 GetTabSortBoxes().clear();
199 pNewTable
->GetTabLines().insert( pNewTable
->GetTabLines().begin(),
200 GetTabLines().begin(), GetTabLines().end() ); // move lines
201 GetTabLines().clear();
203 if( pDoc
->getIDocumentLayoutAccess().GetCurrentViewShell() )
204 m_pDDEType
->DecRefCnt();
206 pTableNd
->SetNewTable( std::move(pNewTable
) ); // replace table
209 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */