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