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