xref: /AOO41X/main/sc/source/ui/docshell/arealink.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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