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