android: Update app-specific/MIME type icons
[LibreOffice.git] / sw / source / core / fields / ddetbl.cxx
blob7324c24c5db94f3a2c40e3650431458343501e17
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
20 #include <doc.hxx>
21 #include <IDocumentSettingAccess.hxx>
22 #include <IDocumentFieldsAccess.hxx>
23 #include <IDocumentLayoutAccess.hxx>
24 #include <contentindex.hxx>
25 #include <ndtxt.hxx>
26 #include <swtable.hxx>
27 #include <swddetbl.hxx>
28 #include <fmtfld.hxx>
29 #include <ddefld.hxx>
30 #include <ndindex.hxx>
31 #include <fldupde.hxx>
32 #include <swtblfmt.hxx>
33 #include <fieldhint.hxx>
34 #include <osl/diagnose.h>
35 #include <pam.hxx>
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)
59 if (bUpdate)
60 ChangeContent();
65 SwDDETable::~SwDDETable()
67 SwDoc* pDoc = GetFrameFormat()->GetDoc();
68 if (!pDoc->IsInDtor() && !m_aLines.empty())
70 assert(m_pTableNode);
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();
81 delete m_pDDEType;
82 m_pDDEType = nullptr;
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
97 NoDDETable();
99 else if(const auto pLinkAnchorHint = dynamic_cast<const sw::LinkAnchorSearchHint*>(&rHint))
101 if(pLinkAnchorHint->m_rpFoundNode)
102 return;
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)
110 return;
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() )
133 return;
134 OSL_ENSURE( !GetTabSortBoxes().empty(), "Table without content?" );
135 if( !GetTabSortBoxes()[0]->GetSttNd()->GetNodes().IsDocNodes() )
136 return;
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()
173 return m_pDDEType;
176 void SwDDETable::NoDDETable()
178 // search table node
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() )
184 return;
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() )
188 return;
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: */