1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_sc.hxx" 30*cdf0e10cSrcweir #ifdef _MSC_VER 31*cdf0e10cSrcweir #pragma optimize("",off) 32*cdf0e10cSrcweir #endif 33*cdf0e10cSrcweir 34*cdf0e10cSrcweir //------------------------------------------------------------------ 35*cdf0e10cSrcweir 36*cdf0e10cSrcweir 37*cdf0e10cSrcweir 38*cdf0e10cSrcweir // INCLUDE --------------------------------------------------------- 39*cdf0e10cSrcweir 40*cdf0e10cSrcweir #include <sfx2/sfxsids.hrc> 41*cdf0e10cSrcweir #include <sfx2/app.hxx> 42*cdf0e10cSrcweir #include <svl/itemset.hxx> 43*cdf0e10cSrcweir #include <svl/stritem.hxx> 44*cdf0e10cSrcweir #include <sfx2/docfile.hxx> 45*cdf0e10cSrcweir #include <sfx2/docfilt.hxx> 46*cdf0e10cSrcweir #include <sfx2/fcontnr.hxx> 47*cdf0e10cSrcweir #include <sfx2/linkmgr.hxx> 48*cdf0e10cSrcweir #include <tools/urlobj.hxx> 49*cdf0e10cSrcweir #include <unotools/transliterationwrapper.hxx> 50*cdf0e10cSrcweir 51*cdf0e10cSrcweir #include "tablink.hxx" 52*cdf0e10cSrcweir 53*cdf0e10cSrcweir #include "scextopt.hxx" 54*cdf0e10cSrcweir #include "table.hxx" 55*cdf0e10cSrcweir #include "document.hxx" 56*cdf0e10cSrcweir #include "docsh.hxx" 57*cdf0e10cSrcweir #include "globstr.hrc" 58*cdf0e10cSrcweir #include "undoblk.hxx" 59*cdf0e10cSrcweir #include "undotab.hxx" 60*cdf0e10cSrcweir #include "global.hxx" 61*cdf0e10cSrcweir #include "hints.hxx" 62*cdf0e10cSrcweir #include "cell.hxx" 63*cdf0e10cSrcweir #include "dociter.hxx" 64*cdf0e10cSrcweir #include "formula/opcode.hxx" 65*cdf0e10cSrcweir 66*cdf0e10cSrcweir struct TableLink_Impl 67*cdf0e10cSrcweir { 68*cdf0e10cSrcweir ScDocShell* m_pDocSh; 69*cdf0e10cSrcweir Window* m_pOldParent; 70*cdf0e10cSrcweir Link m_aEndEditLink; 71*cdf0e10cSrcweir 72*cdf0e10cSrcweir TableLink_Impl() : m_pDocSh( NULL ), m_pOldParent( NULL ) {} 73*cdf0e10cSrcweir }; 74*cdf0e10cSrcweir 75*cdf0e10cSrcweir TYPEINIT1(ScTableLink, ::sfx2::SvBaseLink); 76*cdf0e10cSrcweir 77*cdf0e10cSrcweir //------------------------------------------------------------------------ 78*cdf0e10cSrcweir 79*cdf0e10cSrcweir ScTableLink::ScTableLink(ScDocShell* pDocSh, const String& rFile, 80*cdf0e10cSrcweir const String& rFilter, const String& rOpt, 81*cdf0e10cSrcweir sal_uLong nRefresh ): 82*cdf0e10cSrcweir ::sfx2::SvBaseLink(sfx2::LINKUPDATE_ONCALL,FORMAT_FILE), 83*cdf0e10cSrcweir ScRefreshTimer( nRefresh ), 84*cdf0e10cSrcweir pImpl( new TableLink_Impl ), 85*cdf0e10cSrcweir aFileName(rFile), 86*cdf0e10cSrcweir aFilterName(rFilter), 87*cdf0e10cSrcweir aOptions(rOpt), 88*cdf0e10cSrcweir bInCreate( sal_False ), 89*cdf0e10cSrcweir bInEdit( sal_False ), 90*cdf0e10cSrcweir bAddUndo( sal_True ), 91*cdf0e10cSrcweir bDoPaint( sal_True ) 92*cdf0e10cSrcweir { 93*cdf0e10cSrcweir pImpl->m_pDocSh = pDocSh; 94*cdf0e10cSrcweir } 95*cdf0e10cSrcweir 96*cdf0e10cSrcweir ScTableLink::ScTableLink(SfxObjectShell* pShell, const String& rFile, 97*cdf0e10cSrcweir const String& rFilter, const String& rOpt, 98*cdf0e10cSrcweir sal_uLong nRefresh ): 99*cdf0e10cSrcweir ::sfx2::SvBaseLink(sfx2::LINKUPDATE_ONCALL,FORMAT_FILE), 100*cdf0e10cSrcweir ScRefreshTimer( nRefresh ), 101*cdf0e10cSrcweir pImpl( new TableLink_Impl ), 102*cdf0e10cSrcweir aFileName(rFile), 103*cdf0e10cSrcweir aFilterName(rFilter), 104*cdf0e10cSrcweir aOptions(rOpt), 105*cdf0e10cSrcweir bInCreate( sal_False ), 106*cdf0e10cSrcweir bInEdit( sal_False ), 107*cdf0e10cSrcweir bAddUndo( sal_True ), 108*cdf0e10cSrcweir bDoPaint( sal_True ) 109*cdf0e10cSrcweir { 110*cdf0e10cSrcweir pImpl->m_pDocSh = static_cast< ScDocShell* >( pShell ); 111*cdf0e10cSrcweir SetRefreshHandler( LINK( this, ScTableLink, RefreshHdl ) ); 112*cdf0e10cSrcweir SetRefreshControl( pImpl->m_pDocSh->GetDocument()->GetRefreshTimerControlAddress() ); 113*cdf0e10cSrcweir } 114*cdf0e10cSrcweir 115*cdf0e10cSrcweir __EXPORT ScTableLink::~ScTableLink() 116*cdf0e10cSrcweir { 117*cdf0e10cSrcweir // Verbindung aufheben 118*cdf0e10cSrcweir 119*cdf0e10cSrcweir StopRefreshTimer(); 120*cdf0e10cSrcweir String aEmpty; 121*cdf0e10cSrcweir ScDocument* pDoc = pImpl->m_pDocSh->GetDocument(); 122*cdf0e10cSrcweir SCTAB nCount = pDoc->GetTableCount(); 123*cdf0e10cSrcweir for (SCTAB nTab=0; nTab<nCount; nTab++) 124*cdf0e10cSrcweir if (pDoc->IsLinked(nTab) && pDoc->GetLinkDoc(nTab)==aFileName) 125*cdf0e10cSrcweir pDoc->SetLink( nTab, SC_LINK_NONE, aEmpty, aEmpty, aEmpty, aEmpty, 0 ); 126*cdf0e10cSrcweir delete pImpl; 127*cdf0e10cSrcweir } 128*cdf0e10cSrcweir 129*cdf0e10cSrcweir void __EXPORT ScTableLink::Edit( Window* pParent, const Link& rEndEditHdl ) 130*cdf0e10cSrcweir { 131*cdf0e10cSrcweir // DefModalDialogParent setzen, weil evtl. aus der DocShell beim ConvertFrom 132*cdf0e10cSrcweir // ein Optionen-Dialog kommt... 133*cdf0e10cSrcweir 134*cdf0e10cSrcweir pImpl->m_aEndEditLink = rEndEditHdl; 135*cdf0e10cSrcweir pImpl->m_pOldParent = Application::GetDefDialogParent(); 136*cdf0e10cSrcweir if (pParent) 137*cdf0e10cSrcweir Application::SetDefDialogParent(pParent); 138*cdf0e10cSrcweir 139*cdf0e10cSrcweir bInEdit = sal_True; 140*cdf0e10cSrcweir SvBaseLink::Edit( pParent, LINK( this, ScTableLink, TableEndEditHdl ) ); 141*cdf0e10cSrcweir } 142*cdf0e10cSrcweir 143*cdf0e10cSrcweir void __EXPORT ScTableLink::DataChanged( const String&, 144*cdf0e10cSrcweir const ::com::sun::star::uno::Any& ) 145*cdf0e10cSrcweir { 146*cdf0e10cSrcweir sfx2::LinkManager* pLinkManager=pImpl->m_pDocSh->GetDocument()->GetLinkManager(); 147*cdf0e10cSrcweir if (pLinkManager!=NULL) 148*cdf0e10cSrcweir { 149*cdf0e10cSrcweir String aFile; 150*cdf0e10cSrcweir String aFilter; 151*cdf0e10cSrcweir pLinkManager->GetDisplayNames( this,0,&aFile,NULL,&aFilter); 152*cdf0e10cSrcweir 153*cdf0e10cSrcweir // the file dialog returns the filter name with the application prefix 154*cdf0e10cSrcweir // -> remove prefix 155*cdf0e10cSrcweir ScDocumentLoader::RemoveAppPrefix( aFilter ); 156*cdf0e10cSrcweir 157*cdf0e10cSrcweir if (!bInCreate) 158*cdf0e10cSrcweir Refresh( aFile, aFilter, NULL, GetRefreshDelay() ); // don't load twice 159*cdf0e10cSrcweir } 160*cdf0e10cSrcweir } 161*cdf0e10cSrcweir 162*cdf0e10cSrcweir void __EXPORT ScTableLink::Closed() 163*cdf0e10cSrcweir { 164*cdf0e10cSrcweir // Verknuepfung loeschen: Undo 165*cdf0e10cSrcweir ScDocument* pDoc = pImpl->m_pDocSh->GetDocument(); 166*cdf0e10cSrcweir sal_Bool bUndo (pDoc->IsUndoEnabled()); 167*cdf0e10cSrcweir 168*cdf0e10cSrcweir if (bAddUndo && bUndo) 169*cdf0e10cSrcweir { 170*cdf0e10cSrcweir pImpl->m_pDocSh->GetUndoManager()->AddUndoAction( 171*cdf0e10cSrcweir new ScUndoRemoveLink( pImpl->m_pDocSh, aFileName ) ); 172*cdf0e10cSrcweir 173*cdf0e10cSrcweir bAddUndo = sal_False; // nur einmal 174*cdf0e10cSrcweir } 175*cdf0e10cSrcweir 176*cdf0e10cSrcweir // Verbindung wird im dtor aufgehoben 177*cdf0e10cSrcweir 178*cdf0e10cSrcweir SvBaseLink::Closed(); 179*cdf0e10cSrcweir } 180*cdf0e10cSrcweir 181*cdf0e10cSrcweir sal_Bool ScTableLink::IsUsed() const 182*cdf0e10cSrcweir { 183*cdf0e10cSrcweir return pImpl->m_pDocSh->GetDocument()->HasLink( aFileName, aFilterName, aOptions ); 184*cdf0e10cSrcweir } 185*cdf0e10cSrcweir 186*cdf0e10cSrcweir sal_Bool ScTableLink::Refresh(const String& rNewFile, const String& rNewFilter, 187*cdf0e10cSrcweir const String* pNewOptions, sal_uLong nNewRefresh ) 188*cdf0e10cSrcweir { 189*cdf0e10cSrcweir // Dokument laden 190*cdf0e10cSrcweir 191*cdf0e10cSrcweir if (!rNewFile.Len() || !rNewFilter.Len()) 192*cdf0e10cSrcweir return sal_False; 193*cdf0e10cSrcweir 194*cdf0e10cSrcweir String aNewUrl( ScGlobal::GetAbsDocName( rNewFile, pImpl->m_pDocSh ) ); 195*cdf0e10cSrcweir sal_Bool bNewUrlName = (aNewUrl != aFileName); 196*cdf0e10cSrcweir 197*cdf0e10cSrcweir const SfxFilter* pFilter = pImpl->m_pDocSh->GetFactory().GetFilterContainer()->GetFilter4FilterName(rNewFilter); 198*cdf0e10cSrcweir if (!pFilter) 199*cdf0e10cSrcweir return sal_False; 200*cdf0e10cSrcweir 201*cdf0e10cSrcweir ScDocument* pDoc = pImpl->m_pDocSh->GetDocument(); 202*cdf0e10cSrcweir pDoc->SetInLinkUpdate( sal_True ); 203*cdf0e10cSrcweir 204*cdf0e10cSrcweir sal_Bool bUndo(pDoc->IsUndoEnabled()); 205*cdf0e10cSrcweir 206*cdf0e10cSrcweir // wenn neuer Filter ausgewaehlt wurde, Optionen vergessen 207*cdf0e10cSrcweir if ( rNewFilter != aFilterName ) 208*cdf0e10cSrcweir aOptions.Erase(); 209*cdf0e10cSrcweir if ( pNewOptions ) // Optionen hart angegeben? 210*cdf0e10cSrcweir aOptions = *pNewOptions; 211*cdf0e10cSrcweir 212*cdf0e10cSrcweir // ItemSet immer anlegen, damit die DocShell die Optionen setzen kann 213*cdf0e10cSrcweir SfxItemSet* pSet = new SfxAllItemSet( SFX_APP()->GetPool() ); 214*cdf0e10cSrcweir if ( aOptions.Len() ) 215*cdf0e10cSrcweir pSet->Put( SfxStringItem( SID_FILE_FILTEROPTIONS, aOptions ) ); 216*cdf0e10cSrcweir 217*cdf0e10cSrcweir SfxMedium* pMed = new SfxMedium(aNewUrl, STREAM_STD_READ, sal_False, pFilter, pSet); 218*cdf0e10cSrcweir 219*cdf0e10cSrcweir if ( bInEdit ) // only if using the edit dialog, 220*cdf0e10cSrcweir pMed->UseInteractionHandler( sal_True ); // enable the filter options dialog 221*cdf0e10cSrcweir 222*cdf0e10cSrcweir // aRef->DoClose() will be called explicitly, but it is still more safe to use SfxObjectShellLock here 223*cdf0e10cSrcweir ScDocShell* pSrcShell = new ScDocShell(SFX_CREATE_MODE_INTERNAL); 224*cdf0e10cSrcweir SfxObjectShellLock aRef = pSrcShell; 225*cdf0e10cSrcweir pSrcShell->DoLoad(pMed); 226*cdf0e10cSrcweir 227*cdf0e10cSrcweir // Optionen koennten gesetzt worden sein 228*cdf0e10cSrcweir String aNewOpt = ScDocumentLoader::GetOptions(*pMed); 229*cdf0e10cSrcweir if (!aNewOpt.Len()) 230*cdf0e10cSrcweir aNewOpt = aOptions; 231*cdf0e10cSrcweir 232*cdf0e10cSrcweir // Undo... 233*cdf0e10cSrcweir 234*cdf0e10cSrcweir ScDocument* pUndoDoc = NULL; 235*cdf0e10cSrcweir sal_Bool bFirst = sal_True; 236*cdf0e10cSrcweir if (bAddUndo && bUndo) 237*cdf0e10cSrcweir pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); 238*cdf0e10cSrcweir 239*cdf0e10cSrcweir // Tabellen kopieren 240*cdf0e10cSrcweir 241*cdf0e10cSrcweir ScDocShellModificator aModificator( *pImpl->m_pDocSh ); 242*cdf0e10cSrcweir 243*cdf0e10cSrcweir sal_Bool bNotFound = sal_False; 244*cdf0e10cSrcweir ScDocument* pSrcDoc = pSrcShell->GetDocument(); 245*cdf0e10cSrcweir 246*cdf0e10cSrcweir // #74835# from text filters that don't set the table name, 247*cdf0e10cSrcweir // use the one table regardless of link table name 248*cdf0e10cSrcweir sal_Bool bAutoTab = (pSrcDoc->GetTableCount() == 1) && 249*cdf0e10cSrcweir ScDocShell::HasAutomaticTableName( rNewFilter ); 250*cdf0e10cSrcweir 251*cdf0e10cSrcweir SCTAB nCount = pDoc->GetTableCount(); 252*cdf0e10cSrcweir for (SCTAB nTab=0; nTab<nCount; nTab++) 253*cdf0e10cSrcweir { 254*cdf0e10cSrcweir sal_uInt8 nMode = pDoc->GetLinkMode(nTab); 255*cdf0e10cSrcweir if (nMode && pDoc->GetLinkDoc(nTab)==aFileName) 256*cdf0e10cSrcweir { 257*cdf0e10cSrcweir String aTabName = pDoc->GetLinkTab(nTab); 258*cdf0e10cSrcweir 259*cdf0e10cSrcweir // Undo 260*cdf0e10cSrcweir 261*cdf0e10cSrcweir if (bAddUndo && bUndo) 262*cdf0e10cSrcweir { 263*cdf0e10cSrcweir if (bFirst) 264*cdf0e10cSrcweir pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_True, sal_True ); 265*cdf0e10cSrcweir else 266*cdf0e10cSrcweir pUndoDoc->AddUndoTab( nTab, nTab, sal_True, sal_True ); 267*cdf0e10cSrcweir bFirst = sal_False; 268*cdf0e10cSrcweir ScRange aRange(0,0,nTab,MAXCOL,MAXROW,nTab); 269*cdf0e10cSrcweir pDoc->CopyToDocument(aRange, IDF_ALL, sal_False, pUndoDoc); 270*cdf0e10cSrcweir pUndoDoc->TransferDrawPage( pDoc, nTab, nTab ); 271*cdf0e10cSrcweir pUndoDoc->SetLink( nTab, nMode, aFileName, aFilterName, 272*cdf0e10cSrcweir aOptions, aTabName, GetRefreshDelay() ); 273*cdf0e10cSrcweir } 274*cdf0e10cSrcweir 275*cdf0e10cSrcweir // Tabellenname einer ExtDocRef anpassen 276*cdf0e10cSrcweir 277*cdf0e10cSrcweir if ( bNewUrlName && nMode == SC_LINK_VALUE ) 278*cdf0e10cSrcweir { 279*cdf0e10cSrcweir String aName; 280*cdf0e10cSrcweir pDoc->GetName( nTab, aName ); 281*cdf0e10cSrcweir if ( ScGlobal::GetpTransliteration()->isEqual( 282*cdf0e10cSrcweir ScGlobal::GetDocTabName( aFileName, aTabName ), aName ) ) 283*cdf0e10cSrcweir { 284*cdf0e10cSrcweir pDoc->RenameTab( nTab, 285*cdf0e10cSrcweir ScGlobal::GetDocTabName( aNewUrl, aTabName ), 286*cdf0e10cSrcweir sal_False, sal_True ); // kein RefUpdate, kein ValidTabName 287*cdf0e10cSrcweir } 288*cdf0e10cSrcweir } 289*cdf0e10cSrcweir 290*cdf0e10cSrcweir // kopieren 291*cdf0e10cSrcweir 292*cdf0e10cSrcweir SCTAB nSrcTab = 0; 293*cdf0e10cSrcweir bool bFound = false; 294*cdf0e10cSrcweir /* #i71497# check if external document is loaded successfully, 295*cdf0e10cSrcweir otherwise we may find the empty default sheet "Sheet1" in 296*cdf0e10cSrcweir pSrcDoc, even if the document does not exist. */ 297*cdf0e10cSrcweir if( pMed->GetError() == 0 ) 298*cdf0e10cSrcweir { 299*cdf0e10cSrcweir // no sheet name -> use first sheet 300*cdf0e10cSrcweir if ( aTabName.Len() && !bAutoTab ) 301*cdf0e10cSrcweir bFound = pSrcDoc->GetTable( aTabName, nSrcTab ); 302*cdf0e10cSrcweir else 303*cdf0e10cSrcweir bFound = true; 304*cdf0e10cSrcweir } 305*cdf0e10cSrcweir 306*cdf0e10cSrcweir if (bFound) 307*cdf0e10cSrcweir pDoc->TransferTab( pSrcDoc, nSrcTab, nTab, sal_False, // nicht neu einfuegen 308*cdf0e10cSrcweir (nMode == SC_LINK_VALUE) ); // nur Werte? 309*cdf0e10cSrcweir else 310*cdf0e10cSrcweir { 311*cdf0e10cSrcweir pDoc->DeleteAreaTab( 0,0,MAXCOL,MAXROW, nTab, IDF_ALL ); 312*cdf0e10cSrcweir 313*cdf0e10cSrcweir bool bShowError = true; 314*cdf0e10cSrcweir if ( nMode == SC_LINK_VALUE ) 315*cdf0e10cSrcweir { 316*cdf0e10cSrcweir // #139464# Value link (used with external references in formulas): 317*cdf0e10cSrcweir // Look for formulas that reference the sheet, and put errors in the referenced cells. 318*cdf0e10cSrcweir 319*cdf0e10cSrcweir ScRangeList aErrorCells; // cells on the linked sheets that need error values 320*cdf0e10cSrcweir 321*cdf0e10cSrcweir ScCellIterator aCellIter( pDoc, 0,0,0, MAXCOL,MAXROW,MAXTAB ); // all sheets 322*cdf0e10cSrcweir ScBaseCell* pCell = aCellIter.GetFirst(); 323*cdf0e10cSrcweir while (pCell) 324*cdf0e10cSrcweir { 325*cdf0e10cSrcweir if (pCell->GetCellType() == CELLTYPE_FORMULA) 326*cdf0e10cSrcweir { 327*cdf0e10cSrcweir ScFormulaCell* pFCell = static_cast<ScFormulaCell*>(pCell); 328*cdf0e10cSrcweir 329*cdf0e10cSrcweir ScDetectiveRefIter aRefIter( pFCell ); 330*cdf0e10cSrcweir ScRange aRefRange; 331*cdf0e10cSrcweir while ( aRefIter.GetNextRef( aRefRange ) ) 332*cdf0e10cSrcweir { 333*cdf0e10cSrcweir if ( aRefRange.aStart.Tab() <= nTab && aRefRange.aEnd.Tab() >= nTab ) 334*cdf0e10cSrcweir { 335*cdf0e10cSrcweir // use first cell of range references (don't fill potentially large ranges) 336*cdf0e10cSrcweir 337*cdf0e10cSrcweir aErrorCells.Join( ScRange( aRefRange.aStart ) ); 338*cdf0e10cSrcweir } 339*cdf0e10cSrcweir } 340*cdf0e10cSrcweir } 341*cdf0e10cSrcweir pCell = aCellIter.GetNext(); 342*cdf0e10cSrcweir } 343*cdf0e10cSrcweir 344*cdf0e10cSrcweir sal_uLong nRanges = aErrorCells.Count(); 345*cdf0e10cSrcweir if ( nRanges ) // found any? 346*cdf0e10cSrcweir { 347*cdf0e10cSrcweir ScTokenArray aTokenArr; 348*cdf0e10cSrcweir aTokenArr.AddOpCode( ocNotAvail ); 349*cdf0e10cSrcweir aTokenArr.AddOpCode( ocOpen ); 350*cdf0e10cSrcweir aTokenArr.AddOpCode( ocClose ); 351*cdf0e10cSrcweir aTokenArr.AddOpCode( ocStop ); 352*cdf0e10cSrcweir 353*cdf0e10cSrcweir for (sal_uLong nPos=0; nPos<nRanges; nPos++) 354*cdf0e10cSrcweir { 355*cdf0e10cSrcweir const ScRange* pRange = aErrorCells.GetObject(nPos); 356*cdf0e10cSrcweir SCCOL nStartCol = pRange->aStart.Col(); 357*cdf0e10cSrcweir SCROW nStartRow = pRange->aStart.Row(); 358*cdf0e10cSrcweir SCCOL nEndCol = pRange->aEnd.Col(); 359*cdf0e10cSrcweir SCROW nEndRow = pRange->aEnd.Row(); 360*cdf0e10cSrcweir for (SCROW nRow=nStartRow; nRow<=nEndRow; nRow++) 361*cdf0e10cSrcweir for (SCCOL nCol=nStartCol; nCol<=nEndCol; nCol++) 362*cdf0e10cSrcweir { 363*cdf0e10cSrcweir ScAddress aDestPos( nCol, nRow, nTab ); 364*cdf0e10cSrcweir ScFormulaCell* pNewCell = new ScFormulaCell( pDoc, aDestPos, &aTokenArr ); 365*cdf0e10cSrcweir pDoc->PutCell( aDestPos, pNewCell ); 366*cdf0e10cSrcweir } 367*cdf0e10cSrcweir } 368*cdf0e10cSrcweir 369*cdf0e10cSrcweir bShowError = false; 370*cdf0e10cSrcweir } 371*cdf0e10cSrcweir // if no references were found, insert error message (don't leave the sheet empty) 372*cdf0e10cSrcweir } 373*cdf0e10cSrcweir 374*cdf0e10cSrcweir if ( bShowError ) 375*cdf0e10cSrcweir { 376*cdf0e10cSrcweir // Normal link or no references: put error message on sheet. 377*cdf0e10cSrcweir 378*cdf0e10cSrcweir pDoc->SetString( 0,0,nTab, ScGlobal::GetRscString(STR_LINKERROR) ); 379*cdf0e10cSrcweir pDoc->SetString( 0,1,nTab, ScGlobal::GetRscString(STR_LINKERRORFILE) ); 380*cdf0e10cSrcweir pDoc->SetString( 1,1,nTab, aNewUrl ); 381*cdf0e10cSrcweir pDoc->SetString( 0,2,nTab, ScGlobal::GetRscString(STR_LINKERRORTAB) ); 382*cdf0e10cSrcweir pDoc->SetString( 1,2,nTab, aTabName ); 383*cdf0e10cSrcweir } 384*cdf0e10cSrcweir 385*cdf0e10cSrcweir bNotFound = sal_True; 386*cdf0e10cSrcweir } 387*cdf0e10cSrcweir 388*cdf0e10cSrcweir if ( bNewUrlName || rNewFilter != aFilterName || 389*cdf0e10cSrcweir aNewOpt != aOptions || pNewOptions || 390*cdf0e10cSrcweir nNewRefresh != GetRefreshDelay() ) 391*cdf0e10cSrcweir pDoc->SetLink( nTab, nMode, aNewUrl, rNewFilter, aNewOpt, 392*cdf0e10cSrcweir aTabName, nNewRefresh ); 393*cdf0e10cSrcweir } 394*cdf0e10cSrcweir } 395*cdf0e10cSrcweir 396*cdf0e10cSrcweir // neue Einstellungen merken 397*cdf0e10cSrcweir 398*cdf0e10cSrcweir if ( bNewUrlName ) 399*cdf0e10cSrcweir aFileName = aNewUrl; 400*cdf0e10cSrcweir if ( rNewFilter != aFilterName ) 401*cdf0e10cSrcweir aFilterName = rNewFilter; 402*cdf0e10cSrcweir if ( aNewOpt != aOptions ) 403*cdf0e10cSrcweir aOptions = aNewOpt; 404*cdf0e10cSrcweir 405*cdf0e10cSrcweir // aufraeumen 406*cdf0e10cSrcweir 407*cdf0e10cSrcweir // pSrcShell->DoClose(); 408*cdf0e10cSrcweir aRef->DoClose(); 409*cdf0e10cSrcweir 410*cdf0e10cSrcweir // Undo 411*cdf0e10cSrcweir 412*cdf0e10cSrcweir if (bAddUndo && bUndo) 413*cdf0e10cSrcweir pImpl->m_pDocSh->GetUndoManager()->AddUndoAction( 414*cdf0e10cSrcweir new ScUndoRefreshLink( pImpl->m_pDocSh, pUndoDoc ) ); 415*cdf0e10cSrcweir 416*cdf0e10cSrcweir // Paint (koennen mehrere Tabellen sein) 417*cdf0e10cSrcweir 418*cdf0e10cSrcweir if (bDoPaint) 419*cdf0e10cSrcweir { 420*cdf0e10cSrcweir pImpl->m_pDocSh->PostPaint( ScRange(0,0,0,MAXCOL,MAXROW,MAXTAB), 421*cdf0e10cSrcweir PAINT_GRID | PAINT_TOP | PAINT_LEFT ); 422*cdf0e10cSrcweir aModificator.SetDocumentModified(); 423*cdf0e10cSrcweir } 424*cdf0e10cSrcweir 425*cdf0e10cSrcweir if (bNotFound) 426*cdf0e10cSrcweir { 427*cdf0e10cSrcweir //! Fehler ausgeben ? 428*cdf0e10cSrcweir } 429*cdf0e10cSrcweir 430*cdf0e10cSrcweir pDoc->SetInLinkUpdate( sal_False ); 431*cdf0e10cSrcweir 432*cdf0e10cSrcweir // notify Uno objects (for XRefreshListener) 433*cdf0e10cSrcweir //! also notify Uno objects if file name was changed! 434*cdf0e10cSrcweir ScLinkRefreshedHint aHint; 435*cdf0e10cSrcweir aHint.SetSheetLink( aFileName ); 436*cdf0e10cSrcweir pDoc->BroadcastUno( aHint ); 437*cdf0e10cSrcweir 438*cdf0e10cSrcweir return sal_True; 439*cdf0e10cSrcweir } 440*cdf0e10cSrcweir 441*cdf0e10cSrcweir IMPL_LINK( ScTableLink, RefreshHdl, ScTableLink*, EMPTYARG ) 442*cdf0e10cSrcweir { 443*cdf0e10cSrcweir long nRes = Refresh( aFileName, aFilterName, NULL, GetRefreshDelay() ) != 0; 444*cdf0e10cSrcweir return nRes; 445*cdf0e10cSrcweir } 446*cdf0e10cSrcweir 447*cdf0e10cSrcweir IMPL_LINK( ScTableLink, TableEndEditHdl, ::sfx2::SvBaseLink*, pLink ) 448*cdf0e10cSrcweir { 449*cdf0e10cSrcweir if ( pImpl->m_aEndEditLink.IsSet() ) 450*cdf0e10cSrcweir pImpl->m_aEndEditLink.Call( pLink ); 451*cdf0e10cSrcweir bInEdit = sal_False; 452*cdf0e10cSrcweir Application::SetDefDialogParent( pImpl->m_pOldParent ); 453*cdf0e10cSrcweir return 0; 454*cdf0e10cSrcweir } 455*cdf0e10cSrcweir 456*cdf0e10cSrcweir // === ScDocumentLoader ================================================== 457*cdf0e10cSrcweir 458*cdf0e10cSrcweir String ScDocumentLoader::GetOptions( SfxMedium& rMedium ) // static 459*cdf0e10cSrcweir { 460*cdf0e10cSrcweir SfxItemSet* pSet = rMedium.GetItemSet(); 461*cdf0e10cSrcweir const SfxPoolItem* pItem; 462*cdf0e10cSrcweir if ( pSet && SFX_ITEM_SET == pSet->GetItemState( SID_FILE_FILTEROPTIONS, sal_True, &pItem ) ) 463*cdf0e10cSrcweir return ((const SfxStringItem*)pItem)->GetValue(); 464*cdf0e10cSrcweir 465*cdf0e10cSrcweir return EMPTY_STRING; 466*cdf0e10cSrcweir } 467*cdf0e10cSrcweir 468*cdf0e10cSrcweir sal_Bool ScDocumentLoader::GetFilterName( const String& rFileName, 469*cdf0e10cSrcweir String& rFilter, String& rOptions, 470*cdf0e10cSrcweir sal_Bool bWithContent, sal_Bool bWithInteraction ) // static 471*cdf0e10cSrcweir { 472*cdf0e10cSrcweir TypeId aScType = TYPE(ScDocShell); 473*cdf0e10cSrcweir SfxObjectShell* pDocSh = SfxObjectShell::GetFirst( &aScType ); 474*cdf0e10cSrcweir while ( pDocSh ) 475*cdf0e10cSrcweir { 476*cdf0e10cSrcweir if ( pDocSh->HasName() ) 477*cdf0e10cSrcweir { 478*cdf0e10cSrcweir SfxMedium* pMed = pDocSh->GetMedium(); 479*cdf0e10cSrcweir if ( rFileName == pMed->GetName() ) 480*cdf0e10cSrcweir { 481*cdf0e10cSrcweir rFilter = pMed->GetFilter()->GetFilterName(); 482*cdf0e10cSrcweir rOptions = GetOptions(*pMed); 483*cdf0e10cSrcweir return sal_True; 484*cdf0e10cSrcweir } 485*cdf0e10cSrcweir } 486*cdf0e10cSrcweir pDocSh = SfxObjectShell::GetNext( *pDocSh, &aScType ); 487*cdf0e10cSrcweir } 488*cdf0e10cSrcweir 489*cdf0e10cSrcweir INetURLObject aUrl( rFileName ); 490*cdf0e10cSrcweir INetProtocol eProt = aUrl.GetProtocol(); 491*cdf0e10cSrcweir if ( eProt == INET_PROT_NOT_VALID ) // invalid URL? 492*cdf0e10cSrcweir return sal_False; // abort without creating a medium 493*cdf0e10cSrcweir 494*cdf0e10cSrcweir // Filter-Detection 495*cdf0e10cSrcweir 496*cdf0e10cSrcweir const SfxFilter* pSfxFilter = NULL; 497*cdf0e10cSrcweir SfxMedium* pMedium = new SfxMedium( rFileName, STREAM_STD_READ, sal_False ); 498*cdf0e10cSrcweir if ( pMedium->GetError() == ERRCODE_NONE ) 499*cdf0e10cSrcweir { 500*cdf0e10cSrcweir if ( bWithInteraction ) 501*cdf0e10cSrcweir pMedium->UseInteractionHandler(sal_True); // #i73992# no longer called from GuessFilter 502*cdf0e10cSrcweir 503*cdf0e10cSrcweir SfxFilterMatcher aMatcher( String::CreateFromAscii("scalc") ); 504*cdf0e10cSrcweir if( bWithContent ) 505*cdf0e10cSrcweir aMatcher.GuessFilter( *pMedium, &pSfxFilter ); 506*cdf0e10cSrcweir else 507*cdf0e10cSrcweir aMatcher.GuessFilterIgnoringContent( *pMedium, &pSfxFilter ); 508*cdf0e10cSrcweir } 509*cdf0e10cSrcweir 510*cdf0e10cSrcweir sal_Bool bOK = sal_False; 511*cdf0e10cSrcweir if ( pMedium->GetError() == ERRCODE_NONE ) 512*cdf0e10cSrcweir { 513*cdf0e10cSrcweir if ( pSfxFilter ) 514*cdf0e10cSrcweir rFilter = pSfxFilter->GetFilterName(); 515*cdf0e10cSrcweir else 516*cdf0e10cSrcweir rFilter = ScDocShell::GetOwnFilterName(); // sonst Calc-Datei 517*cdf0e10cSrcweir bOK = (rFilter.Len()>0); 518*cdf0e10cSrcweir } 519*cdf0e10cSrcweir 520*cdf0e10cSrcweir delete pMedium; 521*cdf0e10cSrcweir return bOK; 522*cdf0e10cSrcweir } 523*cdf0e10cSrcweir 524*cdf0e10cSrcweir void ScDocumentLoader::RemoveAppPrefix( String& rFilterName ) // static 525*cdf0e10cSrcweir { 526*cdf0e10cSrcweir String aAppPrefix = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM( STRING_SCAPP )); 527*cdf0e10cSrcweir aAppPrefix.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ": " )); 528*cdf0e10cSrcweir xub_StrLen nPreLen = aAppPrefix.Len(); 529*cdf0e10cSrcweir if ( rFilterName.Copy(0,nPreLen) == aAppPrefix ) 530*cdf0e10cSrcweir rFilterName.Erase(0,nPreLen); 531*cdf0e10cSrcweir } 532*cdf0e10cSrcweir 533*cdf0e10cSrcweir ScDocumentLoader::ScDocumentLoader( const String& rFileName, 534*cdf0e10cSrcweir String& rFilterName, String& rOptions, 535*cdf0e10cSrcweir sal_uInt32 nRekCnt, sal_Bool bWithInteraction ) : 536*cdf0e10cSrcweir pDocShell(0), 537*cdf0e10cSrcweir pMedium(0) 538*cdf0e10cSrcweir { 539*cdf0e10cSrcweir if ( !rFilterName.Len() ) 540*cdf0e10cSrcweir GetFilterName( rFileName, rFilterName, rOptions, sal_True, bWithInteraction ); 541*cdf0e10cSrcweir 542*cdf0e10cSrcweir const SfxFilter* pFilter = ScDocShell::Factory().GetFilterContainer()->GetFilter4FilterName( rFilterName ); 543*cdf0e10cSrcweir 544*cdf0e10cSrcweir // ItemSet immer anlegen, damit die DocShell die Optionen setzen kann 545*cdf0e10cSrcweir SfxItemSet* pSet = new SfxAllItemSet( SFX_APP()->GetPool() ); 546*cdf0e10cSrcweir if ( rOptions.Len() ) 547*cdf0e10cSrcweir pSet->Put( SfxStringItem( SID_FILE_FILTEROPTIONS, rOptions ) ); 548*cdf0e10cSrcweir 549*cdf0e10cSrcweir pMedium = new SfxMedium( rFileName, STREAM_STD_READ, sal_False, pFilter, pSet ); 550*cdf0e10cSrcweir if ( pMedium->GetError() != ERRCODE_NONE ) 551*cdf0e10cSrcweir return ; 552*cdf0e10cSrcweir 553*cdf0e10cSrcweir if ( bWithInteraction ) 554*cdf0e10cSrcweir pMedium->UseInteractionHandler( sal_True ); // to enable the filter options dialog 555*cdf0e10cSrcweir 556*cdf0e10cSrcweir pDocShell = new ScDocShell( SFX_CREATE_MODE_INTERNAL ); 557*cdf0e10cSrcweir aRef = pDocShell; 558*cdf0e10cSrcweir 559*cdf0e10cSrcweir ScDocument* pDoc = pDocShell->GetDocument(); 560*cdf0e10cSrcweir if( pDoc ) 561*cdf0e10cSrcweir { 562*cdf0e10cSrcweir ScExtDocOptions* pExtDocOpt = pDoc->GetExtDocOptions(); 563*cdf0e10cSrcweir if( !pExtDocOpt ) 564*cdf0e10cSrcweir { 565*cdf0e10cSrcweir pExtDocOpt = new ScExtDocOptions; 566*cdf0e10cSrcweir pDoc->SetExtDocOptions( pExtDocOpt ); 567*cdf0e10cSrcweir } 568*cdf0e10cSrcweir pExtDocOpt->GetDocSettings().mnLinkCnt = nRekCnt; 569*cdf0e10cSrcweir } 570*cdf0e10cSrcweir 571*cdf0e10cSrcweir pDocShell->DoLoad( pMedium ); 572*cdf0e10cSrcweir 573*cdf0e10cSrcweir String aNew = GetOptions(*pMedium); // Optionen werden beim Laden per Dialog gesetzt 574*cdf0e10cSrcweir if (aNew.Len() && aNew != rOptions) 575*cdf0e10cSrcweir rOptions = aNew; 576*cdf0e10cSrcweir } 577*cdf0e10cSrcweir 578*cdf0e10cSrcweir ScDocumentLoader::~ScDocumentLoader() 579*cdf0e10cSrcweir { 580*cdf0e10cSrcweir /* if ( pDocShell ) 581*cdf0e10cSrcweir pDocShell->DoClose(); 582*cdf0e10cSrcweir */ 583*cdf0e10cSrcweir if ( aRef.Is() ) 584*cdf0e10cSrcweir aRef->DoClose(); 585*cdf0e10cSrcweir else if ( pMedium ) 586*cdf0e10cSrcweir delete pMedium; 587*cdf0e10cSrcweir } 588*cdf0e10cSrcweir 589*cdf0e10cSrcweir void ScDocumentLoader::ReleaseDocRef() 590*cdf0e10cSrcweir { 591*cdf0e10cSrcweir if ( aRef.Is() ) 592*cdf0e10cSrcweir { 593*cdf0e10cSrcweir // release reference without calling DoClose - caller must 594*cdf0e10cSrcweir // have another reference to the doc and call DoClose later 595*cdf0e10cSrcweir 596*cdf0e10cSrcweir pDocShell = NULL; 597*cdf0e10cSrcweir pMedium = NULL; 598*cdf0e10cSrcweir aRef.Clear(); 599*cdf0e10cSrcweir } 600*cdf0e10cSrcweir } 601*cdf0e10cSrcweir 602*cdf0e10cSrcweir ScDocument* ScDocumentLoader::GetDocument() 603*cdf0e10cSrcweir { 604*cdf0e10cSrcweir return pDocShell ? pDocShell->GetDocument() : 0; 605*cdf0e10cSrcweir } 606*cdf0e10cSrcweir 607*cdf0e10cSrcweir sal_Bool ScDocumentLoader::IsError() const 608*cdf0e10cSrcweir { 609*cdf0e10cSrcweir if ( pDocShell && pMedium ) 610*cdf0e10cSrcweir return pMedium->GetError() != ERRCODE_NONE; 611*cdf0e10cSrcweir else 612*cdf0e10cSrcweir return sal_True; 613*cdf0e10cSrcweir } 614*cdf0e10cSrcweir 615*cdf0e10cSrcweir String ScDocumentLoader::GetTitle() const 616*cdf0e10cSrcweir { 617*cdf0e10cSrcweir if ( pDocShell ) 618*cdf0e10cSrcweir return pDocShell->GetTitle(); 619*cdf0e10cSrcweir else 620*cdf0e10cSrcweir return EMPTY_STRING; 621*cdf0e10cSrcweir } 622*cdf0e10cSrcweir 623