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>
36af36b5edSArrigo 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
AreaLink_ImplAreaLink_Impl67cdf0e10cSrcweir AreaLink_Impl() : m_pDocSh( NULL ), m_pDialog( NULL ) {}
68cdf0e10cSrcweir };
69cdf0e10cSrcweir
70cdf0e10cSrcweir TYPEINIT1(ScAreaLink,::sfx2::SvBaseLink);
71cdf0e10cSrcweir
72cdf0e10cSrcweir //------------------------------------------------------------------------
73cdf0e10cSrcweir
ScAreaLink(SfxObjectShell * pShell,const String & rFile,const String & rFilter,const String & rOpt,const String & rArea,const ScRange & rDest,sal_uLong nRefresh)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
~ScAreaLink()96cdf0e10cSrcweir __EXPORT ScAreaLink::~ScAreaLink()
97cdf0e10cSrcweir {
98cdf0e10cSrcweir StopRefreshTimer();
99cdf0e10cSrcweir delete pImpl;
100cdf0e10cSrcweir }
101cdf0e10cSrcweir
Edit(Window * pParent,const Link &)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
DataChanged(const String &,const::com::sun::star::uno::Any &)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
Closed()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
SetDestArea(const ScRange & rNew)176cdf0e10cSrcweir void ScAreaLink::SetDestArea(const ScRange& rNew)
177cdf0e10cSrcweir {
178cdf0e10cSrcweir aDestArea = rNew; // fuer Undo
179cdf0e10cSrcweir }
180cdf0e10cSrcweir
SetSource(const String & rDoc,const String & rFlt,const String & rOpt,const String & rArea)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
IsEqual(const String & rFile,const String & rFilter,const String & rOpt,const String & rSource,const ScRange & rDest) const195cdf0e10cSrcweir 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<
FindExtRange(ScRange & rRange,ScDocument * pSrcDoc,const String & rAreaName)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
Refresh(const String & rNewFile,const String & rNewFilter,const String & rNewArea,sal_uLong nNewRefresh)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
247af36b5edSArrigo Marchiori // Request for authorization
248af36b5edSArrigo Marchiori sfx2::LinkManager* pLinkMgr = pImpl->m_pDocSh->GetDocument()->GetLinkManager();
249af36b5edSArrigo Marchiori if ( pLinkMgr ) {
250*e1390266SArrigo Marchiori if ( pLinkMgr->urlIsVendor( rNewFile ) )
251*e1390266SArrigo Marchiori return sal_False;
252af36b5edSArrigo Marchiori SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pImpl->m_pDocSh );
253af36b5edSArrigo Marchiori if ( pFrame ) {
254af36b5edSArrigo Marchiori Window* pWindow = &pFrame->GetWindow();
255af36b5edSArrigo Marchiori if ( pWindow ) {
256af36b5edSArrigo Marchiori if ( !pLinkMgr->GetUserAllowsLinkUpdate( pWindow ) ) {
257af36b5edSArrigo Marchiori return sal_False;
258af36b5edSArrigo Marchiori }
259af36b5edSArrigo Marchiori }
260af36b5edSArrigo Marchiori }
261af36b5edSArrigo Marchiori }
262af36b5edSArrigo Marchiori
263cdf0e10cSrcweir String aNewUrl( ScGlobal::GetAbsDocName( rNewFile, pImpl->m_pDocSh ) );
264cdf0e10cSrcweir sal_Bool bNewUrlName = (aNewUrl != aFileName);
265cdf0e10cSrcweir
266cdf0e10cSrcweir const SfxFilter* pFilter = pImpl->m_pDocSh->GetFactory().GetFilterContainer()->GetFilter4FilterName(rNewFilter);
267cdf0e10cSrcweir if (!pFilter)
268cdf0e10cSrcweir return sal_False;
269cdf0e10cSrcweir
270cdf0e10cSrcweir ScDocument* pDoc = pImpl->m_pDocSh->GetDocument();
271cdf0e10cSrcweir
272cdf0e10cSrcweir sal_Bool bUndo (pDoc->IsUndoEnabled());
273cdf0e10cSrcweir pDoc->SetInLinkUpdate( sal_True );
274cdf0e10cSrcweir
275cdf0e10cSrcweir // wenn neuer Filter ausgewaehlt wurde, Optionen vergessen
276cdf0e10cSrcweir if ( rNewFilter != aFilterName )
277cdf0e10cSrcweir aOptions.Erase();
278cdf0e10cSrcweir
279cdf0e10cSrcweir // ItemSet immer anlegen, damit die DocShell die Optionen setzen kann
280cdf0e10cSrcweir SfxItemSet* pSet = new SfxAllItemSet( SFX_APP()->GetPool() );
281cdf0e10cSrcweir if ( aOptions.Len() )
282cdf0e10cSrcweir pSet->Put( SfxStringItem( SID_FILE_FILTEROPTIONS, aOptions ) );
283cdf0e10cSrcweir
284cdf0e10cSrcweir SfxMedium* pMed = new SfxMedium(aNewUrl, STREAM_STD_READ, sal_False, pFilter);
285cdf0e10cSrcweir
286cdf0e10cSrcweir // aRef->DoClose() will be closed explicitly, but it is still more safe to use SfxObjectShellLock here
287cdf0e10cSrcweir ScDocShell* pSrcShell = new ScDocShell(SFX_CREATE_MODE_INTERNAL);
288cdf0e10cSrcweir SfxObjectShellLock aRef = pSrcShell;
289cdf0e10cSrcweir pSrcShell->DoLoad(pMed);
290cdf0e10cSrcweir
291cdf0e10cSrcweir ScDocument* pSrcDoc = pSrcShell->GetDocument();
292cdf0e10cSrcweir
293cdf0e10cSrcweir // Optionen koennten gesetzt worden sein
294cdf0e10cSrcweir String aNewOpt = ScDocumentLoader::GetOptions(*pMed);
295cdf0e10cSrcweir if (!aNewOpt.Len())
296cdf0e10cSrcweir aNewOpt = aOptions;
297cdf0e10cSrcweir
298cdf0e10cSrcweir // correct source range name list for web query import
299cdf0e10cSrcweir String aTempArea;
300cdf0e10cSrcweir
301cdf0e10cSrcweir if( rNewFilter == ScDocShell::GetWebQueryFilterName() )
302cdf0e10cSrcweir aTempArea = ScFormatFilter::Get().GetHTMLRangeNameList( pSrcDoc, rNewArea );
303cdf0e10cSrcweir else
304cdf0e10cSrcweir aTempArea = rNewArea;
305cdf0e10cSrcweir
306cdf0e10cSrcweir // find total size of source area
307cdf0e10cSrcweir SCCOL nWidth = 0;
308cdf0e10cSrcweir SCROW nHeight = 0;
309cdf0e10cSrcweir xub_StrLen nTokenCnt = aTempArea.GetTokenCount( ';' );
310cdf0e10cSrcweir xub_StrLen nStringIx = 0;
311cdf0e10cSrcweir xub_StrLen nToken;
312cdf0e10cSrcweir
313cdf0e10cSrcweir for( nToken = 0; nToken < nTokenCnt; nToken++ )
314cdf0e10cSrcweir {
315cdf0e10cSrcweir String aToken( aTempArea.GetToken( 0, ';', nStringIx ) );
316cdf0e10cSrcweir ScRange aTokenRange;
317cdf0e10cSrcweir if( FindExtRange( aTokenRange, pSrcDoc, aToken ) )
318cdf0e10cSrcweir {
319cdf0e10cSrcweir // columns: find maximum
320cdf0e10cSrcweir nWidth = Max( nWidth, (SCCOL)(aTokenRange.aEnd.Col() - aTokenRange.aStart.Col() + 1) );
321cdf0e10cSrcweir // rows: add row range + 1 empty row
322cdf0e10cSrcweir nHeight += aTokenRange.aEnd.Row() - aTokenRange.aStart.Row() + 2;
323cdf0e10cSrcweir }
324cdf0e10cSrcweir }
325cdf0e10cSrcweir // remove the last empty row
326cdf0e10cSrcweir if( nHeight > 0 )
327cdf0e10cSrcweir nHeight--;
328cdf0e10cSrcweir
329cdf0e10cSrcweir // alte Daten loeschen / neue kopieren
330cdf0e10cSrcweir
331cdf0e10cSrcweir ScAddress aDestPos = aDestArea.aStart;
332cdf0e10cSrcweir SCTAB nDestTab = aDestPos.Tab();
333cdf0e10cSrcweir ScRange aOldRange = aDestArea;
334cdf0e10cSrcweir ScRange aNewRange = aDestArea; // alter Bereich, wenn Datei nicht gefunden o.ae.
335cdf0e10cSrcweir if (nWidth > 0 && nHeight > 0)
336cdf0e10cSrcweir {
337cdf0e10cSrcweir aNewRange.aEnd.SetCol( aNewRange.aStart.Col() + nWidth - 1 );
338cdf0e10cSrcweir aNewRange.aEnd.SetRow( aNewRange.aStart.Row() + nHeight - 1 );
339cdf0e10cSrcweir }
340cdf0e10cSrcweir
341cdf0e10cSrcweir //! check CanFitBlock only if bDoInsert is set?
342cdf0e10cSrcweir sal_Bool bCanDo = ValidColRow( aNewRange.aEnd.Col(), aNewRange.aEnd.Row() ) &&
343cdf0e10cSrcweir pDoc->CanFitBlock( aOldRange, aNewRange );
344cdf0e10cSrcweir if (bCanDo)
345cdf0e10cSrcweir {
346cdf0e10cSrcweir ScDocShellModificator aModificator( *pImpl->m_pDocSh );
347cdf0e10cSrcweir
348cdf0e10cSrcweir SCCOL nOldEndX = aOldRange.aEnd.Col();
349cdf0e10cSrcweir SCROW nOldEndY = aOldRange.aEnd.Row();
350cdf0e10cSrcweir SCCOL nNewEndX = aNewRange.aEnd.Col();
351cdf0e10cSrcweir SCROW nNewEndY = aNewRange.aEnd.Row();
352cdf0e10cSrcweir ScRange aMaxRange( aDestPos,
353cdf0e10cSrcweir ScAddress(Max(nOldEndX,nNewEndX), Max(nOldEndY,nNewEndY), nDestTab) );
354cdf0e10cSrcweir
355cdf0e10cSrcweir // Undo initialisieren
356cdf0e10cSrcweir
357cdf0e10cSrcweir ScDocument* pUndoDoc = NULL;
358cdf0e10cSrcweir ScDocument* pRedoDoc = NULL;
359cdf0e10cSrcweir if ( bAddUndo && bUndo )
360cdf0e10cSrcweir {
361cdf0e10cSrcweir pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
362cdf0e10cSrcweir if ( bDoInsert )
363cdf0e10cSrcweir {
364cdf0e10cSrcweir if ( nNewEndX != nOldEndX || nNewEndY != nOldEndY ) // Bereich veraendert?
365cdf0e10cSrcweir {
366cdf0e10cSrcweir pUndoDoc->InitUndo( pDoc, 0, pDoc->GetTableCount()-1 );
367cdf0e10cSrcweir pDoc->CopyToDocument( 0,0,0,MAXCOL,MAXROW,MAXTAB,
368cdf0e10cSrcweir IDF_FORMULA, sal_False, pUndoDoc ); // alle Formeln
369cdf0e10cSrcweir }
370cdf0e10cSrcweir else
371cdf0e10cSrcweir pUndoDoc->InitUndo( pDoc, nDestTab, nDestTab ); // nur Zieltabelle
372cdf0e10cSrcweir pDoc->CopyToDocument( aOldRange, IDF_ALL & ~IDF_NOTE, sal_False, pUndoDoc );
373cdf0e10cSrcweir }
374cdf0e10cSrcweir else // ohne Einfuegen
375cdf0e10cSrcweir {
376cdf0e10cSrcweir pUndoDoc->InitUndo( pDoc, nDestTab, nDestTab ); // nur Zieltabelle
377cdf0e10cSrcweir pDoc->CopyToDocument( aMaxRange, IDF_ALL & ~IDF_NOTE, sal_False, pUndoDoc );
378cdf0e10cSrcweir }
379cdf0e10cSrcweir }
380cdf0e10cSrcweir
381cdf0e10cSrcweir // Zellen einfuegen / loeschen
382cdf0e10cSrcweir // DeleteAreaTab loescht auch MERGE_FLAG Attribute
383cdf0e10cSrcweir
384cdf0e10cSrcweir if (bDoInsert)
385cdf0e10cSrcweir pDoc->FitBlock( aOldRange, aNewRange ); // incl. loeschen
386cdf0e10cSrcweir else
387cdf0e10cSrcweir pDoc->DeleteAreaTab( aMaxRange, IDF_ALL & ~IDF_NOTE );
388cdf0e10cSrcweir
389cdf0e10cSrcweir // Daten kopieren
390cdf0e10cSrcweir
391cdf0e10cSrcweir if (nWidth > 0 && nHeight > 0)
392cdf0e10cSrcweir {
393cdf0e10cSrcweir ScDocument aClipDoc( SCDOCMODE_CLIP );
394cdf0e10cSrcweir ScRange aNewTokenRange( aNewRange.aStart );
395cdf0e10cSrcweir nStringIx = 0;
396cdf0e10cSrcweir for( nToken = 0; nToken < nTokenCnt; nToken++ )
397cdf0e10cSrcweir {
398cdf0e10cSrcweir String aToken( aTempArea.GetToken( 0, ';', nStringIx ) );
399cdf0e10cSrcweir ScRange aTokenRange;
400cdf0e10cSrcweir if( FindExtRange( aTokenRange, pSrcDoc, aToken ) )
401cdf0e10cSrcweir {
402cdf0e10cSrcweir SCTAB nSrcTab = aTokenRange.aStart.Tab();
403cdf0e10cSrcweir ScMarkData aSourceMark;
404cdf0e10cSrcweir aSourceMark.SelectOneTable( nSrcTab ); // selektieren fuer CopyToClip
405cdf0e10cSrcweir aSourceMark.SetMarkArea( aTokenRange );
406cdf0e10cSrcweir
407cdf0e10cSrcweir ScClipParam aClipParam(aTokenRange, false);
408cdf0e10cSrcweir pSrcDoc->CopyToClip(aClipParam, &aClipDoc, &aSourceMark);
409cdf0e10cSrcweir
410cdf0e10cSrcweir if ( aClipDoc.HasAttrib( 0,0,nSrcTab, MAXCOL,MAXROW,nSrcTab,
411cdf0e10cSrcweir HASATTR_MERGED | HASATTR_OVERLAPPED ) )
412cdf0e10cSrcweir {
413cdf0e10cSrcweir //! ResetAttrib am Dokument !!!
414cdf0e10cSrcweir
415cdf0e10cSrcweir ScPatternAttr aPattern( pSrcDoc->GetPool() );
416cdf0e10cSrcweir aPattern.GetItemSet().Put( ScMergeAttr() ); // Defaults
417cdf0e10cSrcweir aPattern.GetItemSet().Put( ScMergeFlagAttr() );
418cdf0e10cSrcweir aClipDoc.ApplyPatternAreaTab( 0,0, MAXCOL,MAXROW, nSrcTab, aPattern );
419cdf0e10cSrcweir }
420cdf0e10cSrcweir
421cdf0e10cSrcweir aNewTokenRange.aEnd.SetCol( aNewTokenRange.aStart.Col() + (aTokenRange.aEnd.Col() - aTokenRange.aStart.Col()) );
422cdf0e10cSrcweir aNewTokenRange.aEnd.SetRow( aNewTokenRange.aStart.Row() + (aTokenRange.aEnd.Row() - aTokenRange.aStart.Row()) );
423cdf0e10cSrcweir ScMarkData aDestMark;
424cdf0e10cSrcweir aDestMark.SelectOneTable( nDestTab );
425cdf0e10cSrcweir aDestMark.SetMarkArea( aNewTokenRange );
426cdf0e10cSrcweir pDoc->CopyFromClip( aNewTokenRange, aDestMark, IDF_ALL, NULL, &aClipDoc, sal_False );
427cdf0e10cSrcweir aNewTokenRange.aStart.SetRow( aNewTokenRange.aEnd.Row() + 2 );
428cdf0e10cSrcweir }
429cdf0e10cSrcweir }
430cdf0e10cSrcweir }
431cdf0e10cSrcweir else
432cdf0e10cSrcweir {
433cdf0e10cSrcweir String aErr = ScGlobal::GetRscString(STR_LINKERROR);
434cdf0e10cSrcweir pDoc->SetString( aDestPos.Col(), aDestPos.Row(), aDestPos.Tab(), aErr );
435cdf0e10cSrcweir }
436cdf0e10cSrcweir
437cdf0e10cSrcweir // Undo eintragen
438cdf0e10cSrcweir
439cdf0e10cSrcweir if ( bAddUndo && bUndo)
440cdf0e10cSrcweir {
441cdf0e10cSrcweir pRedoDoc = new ScDocument( SCDOCMODE_UNDO );
442cdf0e10cSrcweir pRedoDoc->InitUndo( pDoc, nDestTab, nDestTab );
443cdf0e10cSrcweir pDoc->CopyToDocument( aNewRange, IDF_ALL & ~IDF_NOTE, sal_False, pRedoDoc );
444cdf0e10cSrcweir
445cdf0e10cSrcweir pImpl->m_pDocSh->GetUndoManager()->AddUndoAction(
446cdf0e10cSrcweir new ScUndoUpdateAreaLink( pImpl->m_pDocSh,
447cdf0e10cSrcweir aFileName, aFilterName, aOptions,
448cdf0e10cSrcweir aSourceArea, aOldRange, GetRefreshDelay(),
449cdf0e10cSrcweir aNewUrl, rNewFilter, aNewOpt,
450cdf0e10cSrcweir rNewArea, aNewRange, nNewRefresh,
451cdf0e10cSrcweir pUndoDoc, pRedoDoc, bDoInsert ) );
452cdf0e10cSrcweir }
453cdf0e10cSrcweir
454cdf0e10cSrcweir // neue Einstellungen merken
455cdf0e10cSrcweir
456cdf0e10cSrcweir if ( bNewUrlName )
457cdf0e10cSrcweir aFileName = aNewUrl;
458cdf0e10cSrcweir if ( rNewFilter != aFilterName )
459cdf0e10cSrcweir aFilterName = rNewFilter;
460cdf0e10cSrcweir if ( rNewArea != aSourceArea )
461cdf0e10cSrcweir aSourceArea = rNewArea;
462cdf0e10cSrcweir if ( aNewOpt != aOptions )
463cdf0e10cSrcweir aOptions = aNewOpt;
464cdf0e10cSrcweir
465cdf0e10cSrcweir if ( aNewRange != aDestArea )
466cdf0e10cSrcweir aDestArea = aNewRange;
467cdf0e10cSrcweir
468cdf0e10cSrcweir if ( nNewRefresh != GetRefreshDelay() )
469cdf0e10cSrcweir SetRefreshDelay( nNewRefresh );
470cdf0e10cSrcweir
471cdf0e10cSrcweir SCCOL nPaintEndX = Max( aOldRange.aEnd.Col(), aNewRange.aEnd.Col() );
472cdf0e10cSrcweir SCROW nPaintEndY = Max( aOldRange.aEnd.Row(), aNewRange.aEnd.Row() );
473cdf0e10cSrcweir
474cdf0e10cSrcweir if ( aOldRange.aEnd.Col() != aNewRange.aEnd.Col() )
475cdf0e10cSrcweir nPaintEndX = MAXCOL;
476cdf0e10cSrcweir if ( aOldRange.aEnd.Row() != aNewRange.aEnd.Row() )
477cdf0e10cSrcweir nPaintEndY = MAXROW;
478cdf0e10cSrcweir
479cdf0e10cSrcweir if ( !pImpl->m_pDocSh->AdjustRowHeight( aDestPos.Row(), nPaintEndY, nDestTab ) )
480cdf0e10cSrcweir pImpl->m_pDocSh->PostPaint( aDestPos.Col(),aDestPos.Row(),nDestTab,
481cdf0e10cSrcweir nPaintEndX,nPaintEndY,nDestTab, PAINT_GRID );
482cdf0e10cSrcweir aModificator.SetDocumentModified();
483cdf0e10cSrcweir }
484cdf0e10cSrcweir else
485cdf0e10cSrcweir {
486cdf0e10cSrcweir // CanFitBlock sal_False -> Probleme mit zusammengefassten Zellen
487cdf0e10cSrcweir // oder Tabellengrenze erreicht!
488cdf0e10cSrcweir //! Zellschutz ???
489cdf0e10cSrcweir
490cdf0e10cSrcweir //! Link-Dialog muss Default-Parent setzen
491cdf0e10cSrcweir // "kann keine Zeilen einfuegen"
492cdf0e10cSrcweir InfoBox aBox( Application::GetDefDialogParent(),
493cdf0e10cSrcweir ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_2 ) );
494cdf0e10cSrcweir aBox.Execute();
495cdf0e10cSrcweir }
496cdf0e10cSrcweir
497cdf0e10cSrcweir // aufraeumen
498cdf0e10cSrcweir
499cdf0e10cSrcweir aRef->DoClose();
500cdf0e10cSrcweir
501cdf0e10cSrcweir pDoc->SetInLinkUpdate( sal_False );
502cdf0e10cSrcweir
503cdf0e10cSrcweir if (bCanDo)
504cdf0e10cSrcweir {
505cdf0e10cSrcweir // notify Uno objects (for XRefreshListener)
506cdf0e10cSrcweir //! also notify Uno objects if file name was changed!
507cdf0e10cSrcweir ScLinkRefreshedHint aHint;
508cdf0e10cSrcweir aHint.SetAreaLink( aDestPos );
509cdf0e10cSrcweir pDoc->BroadcastUno( aHint );
510cdf0e10cSrcweir }
511cdf0e10cSrcweir
512cdf0e10cSrcweir return bCanDo;
513cdf0e10cSrcweir }
514cdf0e10cSrcweir
515cdf0e10cSrcweir
IMPL_LINK(ScAreaLink,RefreshHdl,ScAreaLink *,EMPTYARG)516cdf0e10cSrcweir IMPL_LINK( ScAreaLink, RefreshHdl, ScAreaLink*, EMPTYARG )
517cdf0e10cSrcweir {
518cdf0e10cSrcweir long nRes = Refresh( aFileName, aFilterName, aSourceArea,
519cdf0e10cSrcweir GetRefreshDelay() ) != 0;
520cdf0e10cSrcweir return nRes;
521cdf0e10cSrcweir }
522cdf0e10cSrcweir
IMPL_LINK(ScAreaLink,AreaEndEditHdl,void *,EMPTYARG)523cdf0e10cSrcweir IMPL_LINK( ScAreaLink, AreaEndEditHdl, void*, EMPTYARG )
524cdf0e10cSrcweir {
525cdf0e10cSrcweir // #i76514# can't use link argument to access the dialog,
526cdf0e10cSrcweir // because it's the ScLinkedAreaDlg, not AbstractScLinkedAreaDlg
527cdf0e10cSrcweir
528cdf0e10cSrcweir if ( pImpl->m_pDialog && pImpl->m_pDialog->GetResult() == RET_OK )
529cdf0e10cSrcweir {
530cdf0e10cSrcweir aOptions = pImpl->m_pDialog->GetOptions();
531cdf0e10cSrcweir Refresh( pImpl->m_pDialog->GetURL(), pImpl->m_pDialog->GetFilter(),
532cdf0e10cSrcweir pImpl->m_pDialog->GetSource(), pImpl->m_pDialog->GetRefresh() );
533cdf0e10cSrcweir
534cdf0e10cSrcweir // copy source data from members (set in Refresh) into link name for dialog
535cdf0e10cSrcweir String aNewLinkName;
536cdf0e10cSrcweir sfx2::MakeLnkName( aNewLinkName, NULL, aFileName, aSourceArea, &aFilterName );
537cdf0e10cSrcweir SetName( aNewLinkName );
538cdf0e10cSrcweir }
539cdf0e10cSrcweir pImpl->m_pDialog = NULL; // dialog is deleted with parent
540cdf0e10cSrcweir
541cdf0e10cSrcweir return 0;
542cdf0e10cSrcweir }
543cdf0e10cSrcweir
544