1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_sc.hxx" 26 27 // ----------------------------------------------------------------------- 28 29 30 31 // INCLUDE --------------------------------------------------------------- 32 33 #include <sfx2/linkmgr.hxx> 34 #include <tools/debug.hxx> 35 36 #include "areasave.hxx" 37 #include "arealink.hxx" 38 #include "document.hxx" 39 40 // ----------------------------------------------------------------------- 41 42 ScAreaLinkSaver::ScAreaLinkSaver( const ScAreaLink& rSource ) : 43 aFileName ( rSource.GetFile() ), 44 aFilterName ( rSource.GetFilter() ), 45 aOptions ( rSource.GetOptions() ), 46 aSourceArea ( rSource.GetSource() ), 47 aDestArea ( rSource.GetDestArea() ), 48 nRefresh ( rSource.GetRefreshDelay() ) // seconds 49 { 50 } 51 52 ScAreaLinkSaver::ScAreaLinkSaver( const ScAreaLinkSaver& rCopy ) : 53 ScDataObject(), 54 aFileName ( rCopy.aFileName ), 55 aFilterName ( rCopy.aFilterName ), 56 aOptions ( rCopy.aOptions ), 57 aSourceArea ( rCopy.aSourceArea ), 58 aDestArea ( rCopy.aDestArea ), 59 nRefresh ( rCopy.nRefresh ) 60 { 61 } 62 63 ScAreaLinkSaver::~ScAreaLinkSaver() 64 { 65 } 66 67 ScDataObject* ScAreaLinkSaver::Clone() const 68 { 69 return new ScAreaLinkSaver( *this ); 70 } 71 72 sal_Bool ScAreaLinkSaver::IsEqualSource( const ScAreaLink& rCompare ) const 73 { 74 return ( aFileName == rCompare.GetFile() && 75 aFilterName == rCompare.GetFilter() && 76 aOptions == rCompare.GetOptions() && 77 aSourceArea == rCompare.GetSource() && 78 nRefresh == rCompare.GetRefreshDelay() ); 79 } 80 81 sal_Bool ScAreaLinkSaver::IsEqual( const ScAreaLink& rCompare ) const 82 { 83 return ( IsEqualSource( rCompare ) && 84 aDestArea == rCompare.GetDestArea() ); 85 } 86 87 void ScAreaLinkSaver::WriteToLink( ScAreaLink& rLink ) const 88 { 89 rLink.SetDestArea( aDestArea ); 90 } 91 92 void ScAreaLinkSaver::InsertNewLink( ScDocument* pDoc ) const 93 { 94 // (see ScUndoRemoveAreaLink::Undo) 95 96 sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager(); 97 SfxObjectShell* pObjSh = pDoc->GetDocumentShell(); 98 99 if ( pLinkManager && pObjSh ) 100 { 101 ScAreaLink* pLink = new ScAreaLink( pObjSh, aFileName, aFilterName, aOptions, 102 aSourceArea, aDestArea.aStart, nRefresh ); 103 pLink->SetInCreate( sal_True ); 104 pLink->SetDestArea( aDestArea ); 105 pLinkManager->InsertFileLink( *pLink, OBJECT_CLIENT_FILE, aFileName, &aFilterName, &aSourceArea ); 106 pLink->Update(); 107 pLink->SetInCreate( sal_False ); 108 } 109 } 110 111 // ----------------------------------------------------------------------- 112 113 ScAreaLinkSaveCollection::ScAreaLinkSaveCollection() 114 { 115 } 116 117 ScAreaLinkSaveCollection::ScAreaLinkSaveCollection( const ScAreaLinkSaveCollection& rCopy ) : 118 ScCollection( rCopy ) 119 { 120 } 121 122 ScAreaLinkSaveCollection::~ScAreaLinkSaveCollection() 123 { 124 } 125 126 ScDataObject* ScAreaLinkSaveCollection::Clone() const 127 { 128 return new ScAreaLinkSaveCollection( *this ); 129 } 130 131 sal_Bool ScAreaLinkSaveCollection::IsEqual( const ScDocument* pDoc ) const 132 { 133 // IsEqual can be checked in sequence. 134 // Neither ref-update nor removing links will change the order. 135 136 sfx2::LinkManager* pLinkManager = const_cast<ScDocument*>(pDoc)->GetLinkManager(); 137 if (pLinkManager) 138 { 139 sal_uInt16 nPos = 0; 140 const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks(); 141 sal_uInt16 nLinkCount = rLinks.Count(); 142 for (sal_uInt16 i=0; i<nLinkCount; i++) 143 { 144 ::sfx2::SvBaseLink* pBase = *rLinks[i]; 145 if (pBase->ISA(ScAreaLink)) 146 { 147 if ( nPos >= GetCount() || !(*this)[nPos]->IsEqual( *(ScAreaLink*)pBase ) ) 148 return sal_False; 149 150 ++nPos; 151 } 152 } 153 if ( nPos < GetCount() ) 154 return sal_False; // fewer links in the document than in the save collection 155 } 156 157 return sal_True; 158 } 159 160 ScAreaLink* lcl_FindLink( const ::sfx2::SvBaseLinks& rLinks, const ScAreaLinkSaver& rSaver ) 161 { 162 sal_uInt16 nLinkCount = rLinks.Count(); 163 for (sal_uInt16 i=0; i<nLinkCount; i++) 164 { 165 ::sfx2::SvBaseLink* pBase = *rLinks[i]; 166 if ( pBase->ISA(ScAreaLink) && 167 rSaver.IsEqualSource( *static_cast<ScAreaLink*>(pBase) ) ) 168 { 169 return static_cast<ScAreaLink*>(pBase); // found 170 } 171 } 172 return NULL; // not found 173 } 174 175 void ScAreaLinkSaveCollection::Restore( ScDocument* pDoc ) const 176 { 177 // The save collection may contain additional entries that are not in the document. 178 // They must be inserted again. 179 // Entries from the save collection must be searched via source data, as the order 180 // of links changes if deleted entries are re-added to the link manager (always at the end). 181 182 sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager(); 183 if (pLinkManager) 184 { 185 const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks(); 186 sal_uInt16 nSaveCount = GetCount(); 187 for (sal_uInt16 nPos=0; nPos<nSaveCount; nPos++) 188 { 189 ScAreaLinkSaver* pSaver = (*this)[nPos]; 190 ScAreaLink* pLink = lcl_FindLink( rLinks, *pSaver ); 191 if ( pLink ) 192 pSaver->WriteToLink( *pLink ); // restore output position 193 else 194 pSaver->InsertNewLink( pDoc ); // re-insert deleted link 195 } 196 } 197 } 198 199 // static 200 ScAreaLinkSaveCollection* ScAreaLinkSaveCollection::CreateFromDoc( const ScDocument* pDoc ) 201 { 202 ScAreaLinkSaveCollection* pColl = NULL; 203 204 sfx2::LinkManager* pLinkManager = const_cast<ScDocument*>(pDoc)->GetLinkManager(); 205 if (pLinkManager) 206 { 207 const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks(); 208 sal_uInt16 nLinkCount = rLinks.Count(); 209 for (sal_uInt16 i=0; i<nLinkCount; i++) 210 { 211 ::sfx2::SvBaseLink* pBase = *rLinks[i]; 212 if (pBase->ISA(ScAreaLink)) 213 { 214 if (!pColl) 215 pColl = new ScAreaLinkSaveCollection; 216 217 ScAreaLinkSaver* pSaver = new ScAreaLinkSaver( *(ScAreaLink*)pBase ); 218 if (!pColl->Insert(pSaver)) 219 delete pSaver; 220 } 221 } 222 } 223 224 return pColl; 225 } 226 227