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