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