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 10cdf0e10cSrcweir * 11b3f79822SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 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. 19cdf0e10cSrcweir * 20b3f79822SAndrew Rist *************************************************************/ 21b3f79822SAndrew Rist 22b3f79822SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_sc.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir 28cdf0e10cSrcweir 29cdf0e10cSrcweir // INCLUDE --------------------------------------------------------- 30cdf0e10cSrcweir 31cdf0e10cSrcweir #include <sfx2/app.hxx> 32cdf0e10cSrcweir #include <sfx2/docfile.hxx> 33cdf0e10cSrcweir #include <sfx2/fcontnr.hxx> 34cdf0e10cSrcweir #include <sfx2/sfxsids.hrc> 35cdf0e10cSrcweir #include <sfx2/linkmgr.hxx> 36*af36b5edSArrigo Marchiori #include <sfx2/viewfrm.hxx> 37cdf0e10cSrcweir #include <svl/stritem.hxx> 38cdf0e10cSrcweir #include <vcl/msgbox.hxx> 39cdf0e10cSrcweir 40cdf0e10cSrcweir #include "arealink.hxx" 41cdf0e10cSrcweir 42cdf0e10cSrcweir #include "tablink.hxx" 43cdf0e10cSrcweir #include "document.hxx" 44cdf0e10cSrcweir #include "docsh.hxx" 45cdf0e10cSrcweir #include "rangenam.hxx" 46cdf0e10cSrcweir #include "dbcolect.hxx" 47cdf0e10cSrcweir #include "undoblk.hxx" 48cdf0e10cSrcweir #include "globstr.hrc" 49cdf0e10cSrcweir #include "markdata.hxx" 50cdf0e10cSrcweir #include "hints.hxx" 51cdf0e10cSrcweir #include "filter.hxx" 52cdf0e10cSrcweir //CHINA001 #include "linkarea.hxx" // dialog 53cdf0e10cSrcweir 54cdf0e10cSrcweir #include "attrib.hxx" // raus, wenn ResetAttrib am Dokument 55cdf0e10cSrcweir #include "patattr.hxx" // raus, wenn ResetAttrib am Dokument 56cdf0e10cSrcweir #include "docpool.hxx" // raus, wenn ResetAttrib am Dokument 57cdf0e10cSrcweir 58cdf0e10cSrcweir #include "sc.hrc" //CHINA001 59cdf0e10cSrcweir #include "scabstdlg.hxx" //CHINA001 60cdf0e10cSrcweir #include "clipparam.hxx" 61cdf0e10cSrcweir 62cdf0e10cSrcweir struct AreaLink_Impl 63cdf0e10cSrcweir { 64cdf0e10cSrcweir ScDocShell* m_pDocSh; 65cdf0e10cSrcweir AbstractScLinkedAreaDlg* m_pDialog; 66cdf0e10cSrcweir 67cdf0e10cSrcweir AreaLink_Impl() : m_pDocSh( NULL ), m_pDialog( NULL ) {} 68cdf0e10cSrcweir }; 69cdf0e10cSrcweir 70cdf0e10cSrcweir TYPEINIT1(ScAreaLink,::sfx2::SvBaseLink); 71cdf0e10cSrcweir 72cdf0e10cSrcweir //------------------------------------------------------------------------ 73cdf0e10cSrcweir 74cdf0e10cSrcweir ScAreaLink::ScAreaLink( SfxObjectShell* pShell, const String& rFile, 75cdf0e10cSrcweir const String& rFilter, const String& rOpt, 76cdf0e10cSrcweir const String& rArea, const ScRange& rDest, 77cdf0e10cSrcweir sal_uLong nRefresh ) : 78cdf0e10cSrcweir ::sfx2::SvBaseLink(sfx2::LINKUPDATE_ONCALL,FORMAT_FILE), 79cdf0e10cSrcweir ScRefreshTimer ( nRefresh ), 80cdf0e10cSrcweir pImpl ( new AreaLink_Impl() ), 81cdf0e10cSrcweir aFileName (rFile), 82cdf0e10cSrcweir aFilterName (rFilter), 83cdf0e10cSrcweir aOptions (rOpt), 84cdf0e10cSrcweir aSourceArea (rArea), 85cdf0e10cSrcweir aDestArea (rDest), 86cdf0e10cSrcweir bAddUndo (sal_True), 87cdf0e10cSrcweir bInCreate (sal_False), 88cdf0e10cSrcweir bDoInsert (sal_True) 89cdf0e10cSrcweir { 90cdf0e10cSrcweir DBG_ASSERT(pShell->ISA(ScDocShell), "ScAreaLink mit falscher ObjectShell"); 91cdf0e10cSrcweir pImpl->m_pDocSh = static_cast< ScDocShell* >( pShell ); 92cdf0e10cSrcweir SetRefreshHandler( LINK( this, ScAreaLink, RefreshHdl ) ); 93cdf0e10cSrcweir SetRefreshControl( pImpl->m_pDocSh->GetDocument()->GetRefreshTimerControlAddress() ); 94cdf0e10cSrcweir } 95cdf0e10cSrcweir 96cdf0e10cSrcweir __EXPORT ScAreaLink::~ScAreaLink() 97cdf0e10cSrcweir { 98cdf0e10cSrcweir StopRefreshTimer(); 99cdf0e10cSrcweir delete pImpl; 100cdf0e10cSrcweir } 101cdf0e10cSrcweir 102cdf0e10cSrcweir void __EXPORT ScAreaLink::Edit(Window* pParent, const Link& /* rEndEditHdl */ ) 103cdf0e10cSrcweir { 104cdf0e10cSrcweir // use own dialog instead of SvBaseLink::Edit... 105cdf0e10cSrcweir // DefModalDialogParent setzen, weil evtl. aus der DocShell beim ConvertFrom 106cdf0e10cSrcweir // ein Optionen-Dialog kommt... 107cdf0e10cSrcweir 108cdf0e10cSrcweir ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create(); 109cdf0e10cSrcweir DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001 110cdf0e10cSrcweir 111cdf0e10cSrcweir AbstractScLinkedAreaDlg* pDlg = pFact->CreateScLinkedAreaDlg( pParent, RID_SCDLG_LINKAREA); 112cdf0e10cSrcweir DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001 113cdf0e10cSrcweir pDlg->InitFromOldLink( aFileName, aFilterName, aOptions, aSourceArea, GetRefreshDelay() ); 114cdf0e10cSrcweir pImpl->m_pDialog = pDlg; 115cdf0e10cSrcweir pDlg->StartExecuteModal( LINK( this, ScAreaLink, AreaEndEditHdl ) ); 116cdf0e10cSrcweir } 117cdf0e10cSrcweir 118cdf0e10cSrcweir void __EXPORT ScAreaLink::DataChanged( const String&, 119cdf0e10cSrcweir const ::com::sun::star::uno::Any& ) 120cdf0e10cSrcweir { 121cdf0e10cSrcweir // bei bInCreate nichts tun, damit Update gerufen werden kann, um den Status im 122cdf0e10cSrcweir // LinkManager zu setzen, ohne die Daten im Dokument zu aendern 123cdf0e10cSrcweir 124cdf0e10cSrcweir if (bInCreate) 125cdf0e10cSrcweir return; 126cdf0e10cSrcweir 127cdf0e10cSrcweir sfx2::LinkManager* pLinkManager=pImpl->m_pDocSh->GetDocument()->GetLinkManager(); 128cdf0e10cSrcweir if (pLinkManager!=NULL) 129cdf0e10cSrcweir { 130cdf0e10cSrcweir String aFile; 131cdf0e10cSrcweir String aFilter; 132cdf0e10cSrcweir String aArea; 133cdf0e10cSrcweir pLinkManager->GetDisplayNames( this,0,&aFile,&aArea,&aFilter); 134cdf0e10cSrcweir 135cdf0e10cSrcweir // the file dialog returns the filter name with the application prefix 136cdf0e10cSrcweir // -> remove prefix 137cdf0e10cSrcweir ScDocumentLoader::RemoveAppPrefix( aFilter ); 138cdf0e10cSrcweir 139cdf0e10cSrcweir // #81155# dialog doesn't set area, so keep old one 140cdf0e10cSrcweir if ( !aArea.Len() ) 141cdf0e10cSrcweir { 142cdf0e10cSrcweir aArea = aSourceArea; 143cdf0e10cSrcweir 144cdf0e10cSrcweir // adjust in dialog: 145cdf0e10cSrcweir String aNewLinkName; 146cdf0e10cSrcweir sfx2::MakeLnkName( aNewLinkName, NULL, aFile, aArea, &aFilter ); 147cdf0e10cSrcweir SetName( aNewLinkName ); 148cdf0e10cSrcweir } 149cdf0e10cSrcweir 150cdf0e10cSrcweir Refresh( aFile, aFilter, aArea, GetRefreshDelay() ); 151cdf0e10cSrcweir } 152cdf0e10cSrcweir } 153cdf0e10cSrcweir 154cdf0e10cSrcweir void __EXPORT ScAreaLink::Closed() 155cdf0e10cSrcweir { 156cdf0e10cSrcweir // Verknuepfung loeschen: Undo 157cdf0e10cSrcweir 158cdf0e10cSrcweir ScDocument* pDoc = pImpl->m_pDocSh->GetDocument(); 159cdf0e10cSrcweir sal_Bool bUndo (pDoc->IsUndoEnabled()); 160cdf0e10cSrcweir if (bAddUndo && bUndo) 161cdf0e10cSrcweir { 162cdf0e10cSrcweir pImpl->m_pDocSh->GetUndoManager()->AddUndoAction( new ScUndoRemoveAreaLink( pImpl->m_pDocSh, 163cdf0e10cSrcweir aFileName, aFilterName, aOptions, 164cdf0e10cSrcweir aSourceArea, aDestArea, GetRefreshDelay() ) ); 165cdf0e10cSrcweir 166cdf0e10cSrcweir bAddUndo = sal_False; // nur einmal 167cdf0e10cSrcweir } 168cdf0e10cSrcweir 169cdf0e10cSrcweir SCTAB nDestTab = aDestArea.aStart.Tab(); 170cdf0e10cSrcweir if (pDoc->IsStreamValid(nDestTab)) 171cdf0e10cSrcweir pDoc->SetStreamValid(nDestTab, sal_False); 172cdf0e10cSrcweir 173cdf0e10cSrcweir SvBaseLink::Closed(); 174cdf0e10cSrcweir } 175cdf0e10cSrcweir 176cdf0e10cSrcweir void ScAreaLink::SetDestArea(const ScRange& rNew) 177cdf0e10cSrcweir { 178cdf0e10cSrcweir aDestArea = rNew; // fuer Undo 179cdf0e10cSrcweir } 180cdf0e10cSrcweir 181cdf0e10cSrcweir void ScAreaLink::SetSource(const String& rDoc, const String& rFlt, const String& rOpt, 182cdf0e10cSrcweir const String& rArea) 183cdf0e10cSrcweir { 184cdf0e10cSrcweir aFileName = rDoc; 185cdf0e10cSrcweir aFilterName = rFlt; 186cdf0e10cSrcweir aOptions = rOpt; 187cdf0e10cSrcweir aSourceArea = rArea; 188cdf0e10cSrcweir 189cdf0e10cSrcweir // also update link name for dialog 190cdf0e10cSrcweir String aNewLinkName; 191cdf0e10cSrcweir sfx2::MakeLnkName( aNewLinkName, NULL, aFileName, aSourceArea, &aFilterName ); 192cdf0e10cSrcweir SetName( aNewLinkName ); 193cdf0e10cSrcweir } 194cdf0e10cSrcweir 195cdf0e10cSrcweir sal_Bool ScAreaLink::IsEqual( const String& rFile, const String& rFilter, const String& rOpt, 196cdf0e10cSrcweir const String& rSource, const ScRange& rDest ) const 197cdf0e10cSrcweir { 198cdf0e10cSrcweir return aFileName == rFile && aFilterName == rFilter && aOptions == rOpt && 199cdf0e10cSrcweir aSourceArea == rSource && aDestArea.aStart == rDest.aStart; 200cdf0e10cSrcweir } 201cdf0e10cSrcweir 202cdf0e10cSrcweir // find a range with name >rAreaName< in >pSrcDoc<, return it in >rRange< 203cdf0e10cSrcweir sal_Bool ScAreaLink::FindExtRange( ScRange& rRange, ScDocument* pSrcDoc, const String& rAreaName ) 204cdf0e10cSrcweir { 205cdf0e10cSrcweir sal_Bool bFound = sal_False; 206cdf0e10cSrcweir ScRangeName* pNames = pSrcDoc->GetRangeName(); 207cdf0e10cSrcweir sal_uInt16 nPos; 208cdf0e10cSrcweir if (pNames) // benannte Bereiche 209cdf0e10cSrcweir { 210cdf0e10cSrcweir if (pNames->SearchName( rAreaName, nPos )) 211cdf0e10cSrcweir if ( (*pNames)[nPos]->IsValidReference( rRange ) ) 212cdf0e10cSrcweir bFound = sal_True; 213cdf0e10cSrcweir } 214cdf0e10cSrcweir if (!bFound) // Datenbankbereiche 215cdf0e10cSrcweir { 216cdf0e10cSrcweir ScDBCollection* pDBColl = pSrcDoc->GetDBCollection(); 217cdf0e10cSrcweir if (pDBColl) 218cdf0e10cSrcweir if (pDBColl->SearchName( rAreaName, nPos )) 219cdf0e10cSrcweir { 220cdf0e10cSrcweir SCTAB nTab; 221cdf0e10cSrcweir SCCOL nCol1, nCol2; 222cdf0e10cSrcweir SCROW nRow1, nRow2; 223cdf0e10cSrcweir (*pDBColl)[nPos]->GetArea(nTab,nCol1,nRow1,nCol2,nRow2); 224cdf0e10cSrcweir rRange = ScRange( nCol1,nRow1,nTab, nCol2,nRow2,nTab ); 225cdf0e10cSrcweir bFound = sal_True; 226cdf0e10cSrcweir } 227cdf0e10cSrcweir } 228cdf0e10cSrcweir if (!bFound) // direct reference (range or cell) 229cdf0e10cSrcweir { 230cdf0e10cSrcweir ScAddress::Details aDetails(pSrcDoc->GetAddressConvention(), 0, 0); 231cdf0e10cSrcweir if ( rRange.ParseAny( rAreaName, pSrcDoc, aDetails ) & SCA_VALID ) 232cdf0e10cSrcweir bFound = sal_True; 233cdf0e10cSrcweir } 234cdf0e10cSrcweir return bFound; 235cdf0e10cSrcweir } 236cdf0e10cSrcweir 237cdf0e10cSrcweir // ausfuehren: 238cdf0e10cSrcweir 239cdf0e10cSrcweir sal_Bool ScAreaLink::Refresh( const String& rNewFile, const String& rNewFilter, 240cdf0e10cSrcweir const String& rNewArea, sal_uLong nNewRefresh ) 241cdf0e10cSrcweir { 242cdf0e10cSrcweir // Dokument laden - wie TabLink 243cdf0e10cSrcweir 244cdf0e10cSrcweir if (!rNewFile.Len() || !rNewFilter.Len()) 245cdf0e10cSrcweir return sal_False; 246cdf0e10cSrcweir 247*af36b5edSArrigo Marchiori // Request for authorization 248*af36b5edSArrigo Marchiori sfx2::LinkManager* pLinkMgr = pImpl->m_pDocSh->GetDocument()->GetLinkManager(); 249*af36b5edSArrigo Marchiori if ( pLinkMgr ) { 250*af36b5edSArrigo Marchiori SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pImpl->m_pDocSh ); 251*af36b5edSArrigo Marchiori if ( pFrame ) { 252*af36b5edSArrigo Marchiori Window* pWindow = &pFrame->GetWindow(); 253*af36b5edSArrigo Marchiori if ( pWindow ) { 254*af36b5edSArrigo Marchiori if ( !pLinkMgr->GetUserAllowsLinkUpdate( pWindow ) ) { 255*af36b5edSArrigo Marchiori return sal_False; 256*af36b5edSArrigo Marchiori } 257*af36b5edSArrigo Marchiori } 258*af36b5edSArrigo Marchiori } 259*af36b5edSArrigo Marchiori } 260*af36b5edSArrigo Marchiori 261cdf0e10cSrcweir String aNewUrl( ScGlobal::GetAbsDocName( rNewFile, pImpl->m_pDocSh ) ); 262cdf0e10cSrcweir sal_Bool bNewUrlName = (aNewUrl != aFileName); 263cdf0e10cSrcweir 264cdf0e10cSrcweir const SfxFilter* pFilter = pImpl->m_pDocSh->GetFactory().GetFilterContainer()->GetFilter4FilterName(rNewFilter); 265cdf0e10cSrcweir if (!pFilter) 266cdf0e10cSrcweir return sal_False; 267cdf0e10cSrcweir 268cdf0e10cSrcweir ScDocument* pDoc = pImpl->m_pDocSh->GetDocument(); 269cdf0e10cSrcweir 270cdf0e10cSrcweir sal_Bool bUndo (pDoc->IsUndoEnabled()); 271cdf0e10cSrcweir pDoc->SetInLinkUpdate( sal_True ); 272cdf0e10cSrcweir 273cdf0e10cSrcweir // wenn neuer Filter ausgewaehlt wurde, Optionen vergessen 274cdf0e10cSrcweir if ( rNewFilter != aFilterName ) 275cdf0e10cSrcweir aOptions.Erase(); 276cdf0e10cSrcweir 277cdf0e10cSrcweir // ItemSet immer anlegen, damit die DocShell die Optionen setzen kann 278cdf0e10cSrcweir SfxItemSet* pSet = new SfxAllItemSet( SFX_APP()->GetPool() ); 279cdf0e10cSrcweir if ( aOptions.Len() ) 280cdf0e10cSrcweir pSet->Put( SfxStringItem( SID_FILE_FILTEROPTIONS, aOptions ) ); 281cdf0e10cSrcweir 282cdf0e10cSrcweir SfxMedium* pMed = new SfxMedium(aNewUrl, STREAM_STD_READ, sal_False, pFilter); 283cdf0e10cSrcweir 284cdf0e10cSrcweir // aRef->DoClose() will be closed explicitly, but it is still more safe to use SfxObjectShellLock here 285cdf0e10cSrcweir ScDocShell* pSrcShell = new ScDocShell(SFX_CREATE_MODE_INTERNAL); 286cdf0e10cSrcweir SfxObjectShellLock aRef = pSrcShell; 287cdf0e10cSrcweir pSrcShell->DoLoad(pMed); 288cdf0e10cSrcweir 289cdf0e10cSrcweir ScDocument* pSrcDoc = pSrcShell->GetDocument(); 290cdf0e10cSrcweir 291cdf0e10cSrcweir // Optionen koennten gesetzt worden sein 292cdf0e10cSrcweir String aNewOpt = ScDocumentLoader::GetOptions(*pMed); 293cdf0e10cSrcweir if (!aNewOpt.Len()) 294cdf0e10cSrcweir aNewOpt = aOptions; 295cdf0e10cSrcweir 296cdf0e10cSrcweir // correct source range name list for web query import 297cdf0e10cSrcweir String aTempArea; 298cdf0e10cSrcweir 299cdf0e10cSrcweir if( rNewFilter == ScDocShell::GetWebQueryFilterName() ) 300cdf0e10cSrcweir aTempArea = ScFormatFilter::Get().GetHTMLRangeNameList( pSrcDoc, rNewArea ); 301cdf0e10cSrcweir else 302cdf0e10cSrcweir aTempArea = rNewArea; 303cdf0e10cSrcweir 304cdf0e10cSrcweir // find total size of source area 305cdf0e10cSrcweir SCCOL nWidth = 0; 306cdf0e10cSrcweir SCROW nHeight = 0; 307cdf0e10cSrcweir xub_StrLen nTokenCnt = aTempArea.GetTokenCount( ';' ); 308cdf0e10cSrcweir xub_StrLen nStringIx = 0; 309cdf0e10cSrcweir xub_StrLen nToken; 310cdf0e10cSrcweir 311cdf0e10cSrcweir for( nToken = 0; nToken < nTokenCnt; nToken++ ) 312cdf0e10cSrcweir { 313cdf0e10cSrcweir String aToken( aTempArea.GetToken( 0, ';', nStringIx ) ); 314cdf0e10cSrcweir ScRange aTokenRange; 315cdf0e10cSrcweir if( FindExtRange( aTokenRange, pSrcDoc, aToken ) ) 316cdf0e10cSrcweir { 317cdf0e10cSrcweir // columns: find maximum 318cdf0e10cSrcweir nWidth = Max( nWidth, (SCCOL)(aTokenRange.aEnd.Col() - aTokenRange.aStart.Col() + 1) ); 319cdf0e10cSrcweir // rows: add row range + 1 empty row 320cdf0e10cSrcweir nHeight += aTokenRange.aEnd.Row() - aTokenRange.aStart.Row() + 2; 321cdf0e10cSrcweir } 322cdf0e10cSrcweir } 323cdf0e10cSrcweir // remove the last empty row 324cdf0e10cSrcweir if( nHeight > 0 ) 325cdf0e10cSrcweir nHeight--; 326cdf0e10cSrcweir 327cdf0e10cSrcweir // alte Daten loeschen / neue kopieren 328cdf0e10cSrcweir 329cdf0e10cSrcweir ScAddress aDestPos = aDestArea.aStart; 330cdf0e10cSrcweir SCTAB nDestTab = aDestPos.Tab(); 331cdf0e10cSrcweir ScRange aOldRange = aDestArea; 332cdf0e10cSrcweir ScRange aNewRange = aDestArea; // alter Bereich, wenn Datei nicht gefunden o.ae. 333cdf0e10cSrcweir if (nWidth > 0 && nHeight > 0) 334cdf0e10cSrcweir { 335cdf0e10cSrcweir aNewRange.aEnd.SetCol( aNewRange.aStart.Col() + nWidth - 1 ); 336cdf0e10cSrcweir aNewRange.aEnd.SetRow( aNewRange.aStart.Row() + nHeight - 1 ); 337cdf0e10cSrcweir } 338cdf0e10cSrcweir 339cdf0e10cSrcweir //! check CanFitBlock only if bDoInsert is set? 340cdf0e10cSrcweir sal_Bool bCanDo = ValidColRow( aNewRange.aEnd.Col(), aNewRange.aEnd.Row() ) && 341cdf0e10cSrcweir pDoc->CanFitBlock( aOldRange, aNewRange ); 342cdf0e10cSrcweir if (bCanDo) 343cdf0e10cSrcweir { 344cdf0e10cSrcweir ScDocShellModificator aModificator( *pImpl->m_pDocSh ); 345cdf0e10cSrcweir 346cdf0e10cSrcweir SCCOL nOldEndX = aOldRange.aEnd.Col(); 347cdf0e10cSrcweir SCROW nOldEndY = aOldRange.aEnd.Row(); 348cdf0e10cSrcweir SCCOL nNewEndX = aNewRange.aEnd.Col(); 349cdf0e10cSrcweir SCROW nNewEndY = aNewRange.aEnd.Row(); 350cdf0e10cSrcweir ScRange aMaxRange( aDestPos, 351cdf0e10cSrcweir ScAddress(Max(nOldEndX,nNewEndX), Max(nOldEndY,nNewEndY), nDestTab) ); 352cdf0e10cSrcweir 353cdf0e10cSrcweir // Undo initialisieren 354cdf0e10cSrcweir 355cdf0e10cSrcweir ScDocument* pUndoDoc = NULL; 356cdf0e10cSrcweir ScDocument* pRedoDoc = NULL; 357cdf0e10cSrcweir if ( bAddUndo && bUndo ) 358cdf0e10cSrcweir { 359cdf0e10cSrcweir pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); 360cdf0e10cSrcweir if ( bDoInsert ) 361cdf0e10cSrcweir { 362cdf0e10cSrcweir if ( nNewEndX != nOldEndX || nNewEndY != nOldEndY ) // Bereich veraendert? 363cdf0e10cSrcweir { 364cdf0e10cSrcweir pUndoDoc->InitUndo( pDoc, 0, pDoc->GetTableCount()-1 ); 365cdf0e10cSrcweir pDoc->CopyToDocument( 0,0,0,MAXCOL,MAXROW,MAXTAB, 366cdf0e10cSrcweir IDF_FORMULA, sal_False, pUndoDoc ); // alle Formeln 367cdf0e10cSrcweir } 368cdf0e10cSrcweir else 369cdf0e10cSrcweir pUndoDoc->InitUndo( pDoc, nDestTab, nDestTab ); // nur Zieltabelle 370cdf0e10cSrcweir pDoc->CopyToDocument( aOldRange, IDF_ALL & ~IDF_NOTE, sal_False, pUndoDoc ); 371cdf0e10cSrcweir } 372cdf0e10cSrcweir else // ohne Einfuegen 373cdf0e10cSrcweir { 374cdf0e10cSrcweir pUndoDoc->InitUndo( pDoc, nDestTab, nDestTab ); // nur Zieltabelle 375cdf0e10cSrcweir pDoc->CopyToDocument( aMaxRange, IDF_ALL & ~IDF_NOTE, sal_False, pUndoDoc ); 376cdf0e10cSrcweir } 377cdf0e10cSrcweir } 378cdf0e10cSrcweir 379cdf0e10cSrcweir // Zellen einfuegen / loeschen 380cdf0e10cSrcweir // DeleteAreaTab loescht auch MERGE_FLAG Attribute 381cdf0e10cSrcweir 382cdf0e10cSrcweir if (bDoInsert) 383cdf0e10cSrcweir pDoc->FitBlock( aOldRange, aNewRange ); // incl. loeschen 384cdf0e10cSrcweir else 385cdf0e10cSrcweir pDoc->DeleteAreaTab( aMaxRange, IDF_ALL & ~IDF_NOTE ); 386cdf0e10cSrcweir 387cdf0e10cSrcweir // Daten kopieren 388cdf0e10cSrcweir 389cdf0e10cSrcweir if (nWidth > 0 && nHeight > 0) 390cdf0e10cSrcweir { 391cdf0e10cSrcweir ScDocument aClipDoc( SCDOCMODE_CLIP ); 392cdf0e10cSrcweir ScRange aNewTokenRange( aNewRange.aStart ); 393cdf0e10cSrcweir nStringIx = 0; 394cdf0e10cSrcweir for( nToken = 0; nToken < nTokenCnt; nToken++ ) 395cdf0e10cSrcweir { 396cdf0e10cSrcweir String aToken( aTempArea.GetToken( 0, ';', nStringIx ) ); 397cdf0e10cSrcweir ScRange aTokenRange; 398cdf0e10cSrcweir if( FindExtRange( aTokenRange, pSrcDoc, aToken ) ) 399cdf0e10cSrcweir { 400cdf0e10cSrcweir SCTAB nSrcTab = aTokenRange.aStart.Tab(); 401cdf0e10cSrcweir ScMarkData aSourceMark; 402cdf0e10cSrcweir aSourceMark.SelectOneTable( nSrcTab ); // selektieren fuer CopyToClip 403cdf0e10cSrcweir aSourceMark.SetMarkArea( aTokenRange ); 404cdf0e10cSrcweir 405cdf0e10cSrcweir ScClipParam aClipParam(aTokenRange, false); 406cdf0e10cSrcweir pSrcDoc->CopyToClip(aClipParam, &aClipDoc, &aSourceMark); 407cdf0e10cSrcweir 408cdf0e10cSrcweir if ( aClipDoc.HasAttrib( 0,0,nSrcTab, MAXCOL,MAXROW,nSrcTab, 409cdf0e10cSrcweir HASATTR_MERGED | HASATTR_OVERLAPPED ) ) 410cdf0e10cSrcweir { 411cdf0e10cSrcweir //! ResetAttrib am Dokument !!! 412cdf0e10cSrcweir 413cdf0e10cSrcweir ScPatternAttr aPattern( pSrcDoc->GetPool() ); 414cdf0e10cSrcweir aPattern.GetItemSet().Put( ScMergeAttr() ); // Defaults 415cdf0e10cSrcweir aPattern.GetItemSet().Put( ScMergeFlagAttr() ); 416cdf0e10cSrcweir aClipDoc.ApplyPatternAreaTab( 0,0, MAXCOL,MAXROW, nSrcTab, aPattern ); 417cdf0e10cSrcweir } 418cdf0e10cSrcweir 419cdf0e10cSrcweir aNewTokenRange.aEnd.SetCol( aNewTokenRange.aStart.Col() + (aTokenRange.aEnd.Col() - aTokenRange.aStart.Col()) ); 420cdf0e10cSrcweir aNewTokenRange.aEnd.SetRow( aNewTokenRange.aStart.Row() + (aTokenRange.aEnd.Row() - aTokenRange.aStart.Row()) ); 421cdf0e10cSrcweir ScMarkData aDestMark; 422cdf0e10cSrcweir aDestMark.SelectOneTable( nDestTab ); 423cdf0e10cSrcweir aDestMark.SetMarkArea( aNewTokenRange ); 424cdf0e10cSrcweir pDoc->CopyFromClip( aNewTokenRange, aDestMark, IDF_ALL, NULL, &aClipDoc, sal_False ); 425cdf0e10cSrcweir aNewTokenRange.aStart.SetRow( aNewTokenRange.aEnd.Row() + 2 ); 426cdf0e10cSrcweir } 427cdf0e10cSrcweir } 428cdf0e10cSrcweir } 429cdf0e10cSrcweir else 430cdf0e10cSrcweir { 431cdf0e10cSrcweir String aErr = ScGlobal::GetRscString(STR_LINKERROR); 432cdf0e10cSrcweir pDoc->SetString( aDestPos.Col(), aDestPos.Row(), aDestPos.Tab(), aErr ); 433cdf0e10cSrcweir } 434cdf0e10cSrcweir 435cdf0e10cSrcweir // Undo eintragen 436cdf0e10cSrcweir 437cdf0e10cSrcweir if ( bAddUndo && bUndo) 438cdf0e10cSrcweir { 439cdf0e10cSrcweir pRedoDoc = new ScDocument( SCDOCMODE_UNDO ); 440cdf0e10cSrcweir pRedoDoc->InitUndo( pDoc, nDestTab, nDestTab ); 441cdf0e10cSrcweir pDoc->CopyToDocument( aNewRange, IDF_ALL & ~IDF_NOTE, sal_False, pRedoDoc ); 442cdf0e10cSrcweir 443cdf0e10cSrcweir pImpl->m_pDocSh->GetUndoManager()->AddUndoAction( 444cdf0e10cSrcweir new ScUndoUpdateAreaLink( pImpl->m_pDocSh, 445cdf0e10cSrcweir aFileName, aFilterName, aOptions, 446cdf0e10cSrcweir aSourceArea, aOldRange, GetRefreshDelay(), 447cdf0e10cSrcweir aNewUrl, rNewFilter, aNewOpt, 448cdf0e10cSrcweir rNewArea, aNewRange, nNewRefresh, 449cdf0e10cSrcweir pUndoDoc, pRedoDoc, bDoInsert ) ); 450cdf0e10cSrcweir } 451cdf0e10cSrcweir 452cdf0e10cSrcweir // neue Einstellungen merken 453cdf0e10cSrcweir 454cdf0e10cSrcweir if ( bNewUrlName ) 455cdf0e10cSrcweir aFileName = aNewUrl; 456cdf0e10cSrcweir if ( rNewFilter != aFilterName ) 457cdf0e10cSrcweir aFilterName = rNewFilter; 458cdf0e10cSrcweir if ( rNewArea != aSourceArea ) 459cdf0e10cSrcweir aSourceArea = rNewArea; 460cdf0e10cSrcweir if ( aNewOpt != aOptions ) 461cdf0e10cSrcweir aOptions = aNewOpt; 462cdf0e10cSrcweir 463cdf0e10cSrcweir if ( aNewRange != aDestArea ) 464cdf0e10cSrcweir aDestArea = aNewRange; 465cdf0e10cSrcweir 466cdf0e10cSrcweir if ( nNewRefresh != GetRefreshDelay() ) 467cdf0e10cSrcweir SetRefreshDelay( nNewRefresh ); 468cdf0e10cSrcweir 469cdf0e10cSrcweir SCCOL nPaintEndX = Max( aOldRange.aEnd.Col(), aNewRange.aEnd.Col() ); 470cdf0e10cSrcweir SCROW nPaintEndY = Max( aOldRange.aEnd.Row(), aNewRange.aEnd.Row() ); 471cdf0e10cSrcweir 472cdf0e10cSrcweir if ( aOldRange.aEnd.Col() != aNewRange.aEnd.Col() ) 473cdf0e10cSrcweir nPaintEndX = MAXCOL; 474cdf0e10cSrcweir if ( aOldRange.aEnd.Row() != aNewRange.aEnd.Row() ) 475cdf0e10cSrcweir nPaintEndY = MAXROW; 476cdf0e10cSrcweir 477cdf0e10cSrcweir if ( !pImpl->m_pDocSh->AdjustRowHeight( aDestPos.Row(), nPaintEndY, nDestTab ) ) 478cdf0e10cSrcweir pImpl->m_pDocSh->PostPaint( aDestPos.Col(),aDestPos.Row(),nDestTab, 479cdf0e10cSrcweir nPaintEndX,nPaintEndY,nDestTab, PAINT_GRID ); 480cdf0e10cSrcweir aModificator.SetDocumentModified(); 481cdf0e10cSrcweir } 482cdf0e10cSrcweir else 483cdf0e10cSrcweir { 484cdf0e10cSrcweir // CanFitBlock sal_False -> Probleme mit zusammengefassten Zellen 485cdf0e10cSrcweir // oder Tabellengrenze erreicht! 486cdf0e10cSrcweir //! Zellschutz ??? 487cdf0e10cSrcweir 488cdf0e10cSrcweir //! Link-Dialog muss Default-Parent setzen 489cdf0e10cSrcweir // "kann keine Zeilen einfuegen" 490cdf0e10cSrcweir InfoBox aBox( Application::GetDefDialogParent(), 491cdf0e10cSrcweir ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_2 ) ); 492cdf0e10cSrcweir aBox.Execute(); 493cdf0e10cSrcweir } 494cdf0e10cSrcweir 495cdf0e10cSrcweir // aufraeumen 496cdf0e10cSrcweir 497cdf0e10cSrcweir aRef->DoClose(); 498cdf0e10cSrcweir 499cdf0e10cSrcweir pDoc->SetInLinkUpdate( sal_False ); 500cdf0e10cSrcweir 501cdf0e10cSrcweir if (bCanDo) 502cdf0e10cSrcweir { 503cdf0e10cSrcweir // notify Uno objects (for XRefreshListener) 504cdf0e10cSrcweir //! also notify Uno objects if file name was changed! 505cdf0e10cSrcweir ScLinkRefreshedHint aHint; 506cdf0e10cSrcweir aHint.SetAreaLink( aDestPos ); 507cdf0e10cSrcweir pDoc->BroadcastUno( aHint ); 508cdf0e10cSrcweir } 509cdf0e10cSrcweir 510cdf0e10cSrcweir return bCanDo; 511cdf0e10cSrcweir } 512cdf0e10cSrcweir 513cdf0e10cSrcweir 514cdf0e10cSrcweir IMPL_LINK( ScAreaLink, RefreshHdl, ScAreaLink*, EMPTYARG ) 515cdf0e10cSrcweir { 516cdf0e10cSrcweir long nRes = Refresh( aFileName, aFilterName, aSourceArea, 517cdf0e10cSrcweir GetRefreshDelay() ) != 0; 518cdf0e10cSrcweir return nRes; 519cdf0e10cSrcweir } 520cdf0e10cSrcweir 521cdf0e10cSrcweir IMPL_LINK( ScAreaLink, AreaEndEditHdl, void*, EMPTYARG ) 522cdf0e10cSrcweir { 523cdf0e10cSrcweir // #i76514# can't use link argument to access the dialog, 524cdf0e10cSrcweir // because it's the ScLinkedAreaDlg, not AbstractScLinkedAreaDlg 525cdf0e10cSrcweir 526cdf0e10cSrcweir if ( pImpl->m_pDialog && pImpl->m_pDialog->GetResult() == RET_OK ) 527cdf0e10cSrcweir { 528cdf0e10cSrcweir aOptions = pImpl->m_pDialog->GetOptions(); 529cdf0e10cSrcweir Refresh( pImpl->m_pDialog->GetURL(), pImpl->m_pDialog->GetFilter(), 530cdf0e10cSrcweir pImpl->m_pDialog->GetSource(), pImpl->m_pDialog->GetRefresh() ); 531cdf0e10cSrcweir 532cdf0e10cSrcweir // copy source data from members (set in Refresh) into link name for dialog 533cdf0e10cSrcweir String aNewLinkName; 534cdf0e10cSrcweir sfx2::MakeLnkName( aNewLinkName, NULL, aFileName, aSourceArea, &aFilterName ); 535cdf0e10cSrcweir SetName( aNewLinkName ); 536cdf0e10cSrcweir } 537cdf0e10cSrcweir pImpl->m_pDialog = NULL; // dialog is deleted with parent 538cdf0e10cSrcweir 539cdf0e10cSrcweir return 0; 540cdf0e10cSrcweir } 541cdf0e10cSrcweir 542