xref: /trunk/main/sc/source/ui/docshell/docsh6.cxx (revision b3f79822)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sc.hxx"
26 
27 // System - Includes -----------------------------------------------------
28 
29 
30 
31 #ifndef PCH
32 #include "scitems.hxx"
33 
34 #include <svx/pageitem.hxx>
35 #include <vcl/virdev.hxx>
36 #include <sfx2/linkmgr.hxx>
37 #endif
38 
39 // INCLUDE ---------------------------------------------------------------
40 
41 //#include <svxlink.hxx>
42 
43 #include "docsh.hxx"
44 
45 #include "stlsheet.hxx"
46 #include "stlpool.hxx"
47 #include "global.hxx"
48 #include "viewdata.hxx"
49 #include "tabvwsh.hxx"
50 #include "tablink.hxx"
51 #include "collect.hxx"
52 
53 struct ScStylePair
54 {
55 	SfxStyleSheetBase *pSource;
56 	SfxStyleSheetBase *pDest;
57 };
58 
59 
60 // STATIC DATA -----------------------------------------------------------
61 
62 //----------------------------------------------------------------------
63 
64 //
65 //	Ole
66 //
67 
68 void __EXPORT ScDocShell::SetVisArea( const Rectangle & rVisArea )
69 {
70 	//	with the SnapVisArea call in SetVisAreaOrSize, it's safe to always
71 	//	use both the size and position of the VisArea
72 	SetVisAreaOrSize( rVisArea, sal_True );
73 }
74 
75 void lcl_SetTopRight( Rectangle& rRect, const Point& rPos )
76 {
77     Size aSize = rRect.GetSize();
78     rRect.Right() = rPos.X();
79     rRect.Left() = rPos.X() - aSize.Width() + 1;
80     rRect.Top() = rPos.Y();
81     rRect.Bottom() = rPos.Y() + aSize.Height() - 1;
82 }
83 
84 void ScDocShell::SetVisAreaOrSize( const Rectangle& rVisArea, sal_Bool bModifyStart )
85 {
86     sal_Bool bNegativePage = aDocument.IsNegativePage( aDocument.GetVisibleTab() );
87 
88 	Rectangle aArea = rVisArea;
89 	if (bModifyStart)
90 	{
91 	    // when loading, don't check for negative values, because the sheet orientation
92 	    // might be set later
93     	if ( !aDocument.IsImportingXML() )
94     	{
95     		if ( ( bNegativePage ? (aArea.Right() > 0) : (aArea.Left() < 0) ) || aArea.Top() < 0 )
96     		{
97     			//	VisArea start position can't be negative.
98     			//	Move the VisArea, otherwise only the upper left position would
99     			//	be changed in SnapVisArea, and the size would be wrong.
100 
101                 Point aNewPos( 0, Max( aArea.Top(), (long) 0 ) );
102                 if ( bNegativePage )
103                 {
104                     aNewPos.X() = Min( aArea.Right(), (long) 0 );
105                     lcl_SetTopRight( aArea, aNewPos );
106                 }
107                 else
108                 {
109                     aNewPos.X() = Max( aArea.Left(), (long) 0 );
110                     aArea.SetPos( aNewPos );
111                 }
112     		}
113     	}
114 	}
115 	else
116     {
117         Rectangle aOldVisArea = SfxObjectShell::GetVisArea();
118         if ( bNegativePage )
119             lcl_SetTopRight( aArea, aOldVisArea.TopRight() );
120         else
121             aArea.SetPos( aOldVisArea.TopLeft() );
122     }
123 
124 	//		hier Position anpassen!
125 
126 	//	#92248# when loading an ole object, the VisArea is set from the document's
127 	//	view settings and must be used as-is (document content may not be complete yet).
128 	if ( !aDocument.IsImportingXML() )
129 		aDocument.SnapVisArea( aArea );
130 
131     //TODO/LATER: it's unclear which IPEnv is used here
132     /*
133 	SvInPlaceEnvironment* pEnv = GetIPEnv();
134 	if (pEnv)
135 	{
136 		Window* pWin = pEnv->GetEditWin();
137 		pEnv->MakeScale( aArea.GetSize(), MAP_100TH_MM,
138 							pWin->LogicToPixel( aArea.GetSize() ) );
139     } */
140 
141     //TODO/LATER: formerly in SvInplaceObject
142     SfxObjectShell::SetVisArea( aArea );
143 
144 	if (bIsInplace)						// Zoom in der InPlace View einstellen
145 	{
146 		ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
147 		if (pViewSh)
148 		{
149 			if (pViewSh->GetViewData()->GetDocShell() == this)
150 				pViewSh->UpdateOleZoom();
151 		}
152 		//else
153 		//	DataChanged( SvDataType() );			// fuer Zuppeln wenn nicht IP-aktiv
154 	}
155 
156 	if (aDocument.IsEmbedded())
157 	{
158 		ScRange aOld;
159 		aDocument.GetEmbedded( aOld);
160 		aDocument.SetEmbedded( aArea );
161 		ScRange aNew;
162 		aDocument.GetEmbedded( aNew);
163 		if (aOld != aNew)
164 			PostPaint(0,0,0,MAXCOL,MAXROW,MAXTAB,PAINT_GRID);
165 
166         //TODO/LATER: currently not implemented
167         //ViewChanged( ASPECT_CONTENT );          // auch im Container anzeigen
168 	}
169 }
170 
171 sal_Bool ScDocShell::IsOle()
172 {
173 	return (GetCreateMode() == SFX_CREATE_MODE_EMBEDDED);
174 }
175 
176 void ScDocShell::UpdateOle( const ScViewData* pViewData, sal_Bool bSnapSize )
177 {
178 	//	wenn's gar nicht Ole ist, kann man sich die Berechnungen sparen
179 	//	(VisArea wird dann beim Save wieder zurueckgesetzt)
180 
181 	if (GetCreateMode() == SFX_CREATE_MODE_STANDARD)
182 		return;
183 
184 	DBG_ASSERT(pViewData,"pViewData==0 bei ScDocShell::UpdateOle");
185 
186     Rectangle aOldArea = SfxObjectShell::GetVisArea();
187 	Rectangle aNewArea = aOldArea;
188 
189 	sal_Bool bChange = sal_False;
190 	sal_Bool bEmbedded = aDocument.IsEmbedded();
191 	if (bEmbedded)
192 		aNewArea = aDocument.GetEmbeddedRect();
193 	else
194 	{
195 	    SCTAB nTab = pViewData->GetTabNo();
196 		if ( nTab != aDocument.GetVisibleTab() )
197 		{
198 			aDocument.SetVisibleTab( nTab );
199 			bChange = sal_True;
200 		}
201 
202         sal_Bool bNegativePage = aDocument.IsNegativePage( nTab );
203 		SCCOL nX = pViewData->GetPosX(SC_SPLIT_LEFT);
204 		SCROW nY = pViewData->GetPosY(SC_SPLIT_BOTTOM);
205         Rectangle aMMRect = aDocument.GetMMRect( nX,nY, nX,nY, nTab );
206         if (bNegativePage)
207             lcl_SetTopRight( aNewArea, aMMRect.TopRight() );
208         else
209             aNewArea.SetPos( aMMRect.TopLeft() );
210 		if (bSnapSize)
211 			aDocument.SnapVisArea(aNewArea);            // uses the new VisibleTab
212 	}
213 
214 	if (aNewArea != aOldArea)
215 	{
216 		SetVisAreaOrSize( aNewArea, sal_True );	// hier muss auch der Start angepasst werden
217 		bChange = sal_True;
218 	}
219 
220 //	if (bChange)
221 //		DataChanged( SvDataType() );		//! passiert auch bei SetModified
222 }
223 
224 //
225 //	Style-Krempel fuer Organizer etc.
226 //
227 
228 SfxStyleSheetBasePool* __EXPORT ScDocShell::GetStyleSheetPool()
229 {
230 	return (SfxStyleSheetBasePool*)aDocument.GetStyleSheetPool();
231 }
232 
233 
234 //	nach dem Laden von Vorlagen aus einem anderen Dokment (LoadStyles, Insert)
235 //	muessen die SetItems (ATTR_PAGE_HEADERSET, ATTR_PAGE_FOOTERSET) auf den richtigen
236 //	Pool umgesetzt werden, bevor der Quell-Pool geloescht wird.
237 
238 void lcl_AdjustPool( SfxStyleSheetBasePool* pStylePool )
239 {
240 	pStylePool->SetSearchMask(SFX_STYLE_FAMILY_PAGE, 0xffff);
241 	SfxStyleSheetBase *pStyle = pStylePool->First();
242 	while ( pStyle )
243 	{
244 		SfxItemSet& rStyleSet = pStyle->GetItemSet();
245 
246 		const SfxPoolItem* pItem;
247 		if (rStyleSet.GetItemState(ATTR_PAGE_HEADERSET,sal_False,&pItem) == SFX_ITEM_SET)
248 		{
249 			SfxItemSet& rSrcSet = ((SvxSetItem*)pItem)->GetItemSet();
250 			SfxItemSet* pDestSet = new SfxItemSet(*rStyleSet.GetPool(),rSrcSet.GetRanges());
251 			pDestSet->Put(rSrcSet);
252 			rStyleSet.Put(SvxSetItem(ATTR_PAGE_HEADERSET,pDestSet));
253 		}
254 		if (rStyleSet.GetItemState(ATTR_PAGE_FOOTERSET,sal_False,&pItem) == SFX_ITEM_SET)
255 		{
256 			SfxItemSet& rSrcSet = ((SvxSetItem*)pItem)->GetItemSet();
257 			SfxItemSet* pDestSet = new SfxItemSet(*rStyleSet.GetPool(),rSrcSet.GetRanges());
258 			pDestSet->Put(rSrcSet);
259 			rStyleSet.Put(SvxSetItem(ATTR_PAGE_FOOTERSET,pDestSet));
260 		}
261 
262 		pStyle = pStylePool->Next();
263 	}
264 }
265 
266 void __EXPORT ScDocShell::LoadStyles( SfxObjectShell &rSource )
267 {
268 	aDocument.StylesToNames();
269 
270 	SfxObjectShell::LoadStyles(rSource);
271 	lcl_AdjustPool( GetStyleSheetPool() );		// SetItems anpassen
272 
273 	aDocument.UpdStlShtPtrsFrmNms();
274 
275 	UpdateAllRowHeights();
276 
277 		//	Paint
278 
279 	PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_GRID | PAINT_LEFT );
280 }
281 
282 void ScDocShell::LoadStylesArgs( ScDocShell& rSource, sal_Bool bReplace, sal_Bool bCellStyles, sal_Bool bPageStyles )
283 {
284 	//	similar to LoadStyles, but with selectable behavior for XStyleLoader::loadStylesFromURL call
285 
286 	if ( !bCellStyles && !bPageStyles )		// nothing to do
287 		return;
288 
289 	ScStyleSheetPool* pSourcePool = rSource.GetDocument()->GetStyleSheetPool();
290 	ScStyleSheetPool* pDestPool = aDocument.GetStyleSheetPool();
291 
292 	SfxStyleFamily eFamily = bCellStyles ?
293 			( bPageStyles ? SFX_STYLE_FAMILY_ALL : SFX_STYLE_FAMILY_PARA ) :
294 			SFX_STYLE_FAMILY_PAGE;
295 	SfxStyleSheetIterator aIter( pSourcePool, eFamily );
296 	sal_uInt16 nSourceCount = aIter.Count();
297 	if ( nSourceCount == 0 )
298 		return;								// no source styles
299 
300 	ScStylePair* pStyles = new ScStylePair[ nSourceCount ];
301 	sal_uInt16 nFound = 0;
302 
303 	//	first create all new styles
304 
305 	SfxStyleSheetBase* pSourceStyle = aIter.First();
306 	while (pSourceStyle)
307 	{
308 		String aName = pSourceStyle->GetName();
309 		SfxStyleSheetBase* pDestStyle = pDestPool->Find( pSourceStyle->GetName(), pSourceStyle->GetFamily() );
310 		if ( pDestStyle )
311 		{
312 			// touch existing styles only if replace flag is set
313 			if ( bReplace )
314 			{
315 				pStyles[nFound].pSource = pSourceStyle;
316 				pStyles[nFound].pDest = pDestStyle;
317 				++nFound;
318 			}
319 		}
320 		else
321 		{
322 			pStyles[nFound].pSource = pSourceStyle;
323 			pStyles[nFound].pDest = &pDestPool->Make( aName, pSourceStyle->GetFamily(), pSourceStyle->GetMask() );
324 			++nFound;
325 		}
326 
327 		pSourceStyle = aIter.Next();
328 	}
329 
330 	//	then copy contents (after inserting all styles, for parent etc.)
331 
332 	for ( sal_uInt16 i = 0; i < nFound; ++i )
333 	{
334 		pStyles[i].pDest->GetItemSet().PutExtended(
335 			pStyles[i].pSource->GetItemSet(), SFX_ITEM_DONTCARE, SFX_ITEM_DEFAULT);
336 		if(pStyles[i].pSource->HasParentSupport())
337 			pStyles[i].pDest->SetParent(pStyles[i].pSource->GetParent());
338 		// follow is never used
339 	}
340 
341 	lcl_AdjustPool( GetStyleSheetPool() );		// adjust SetItems
342 	UpdateAllRowHeights();
343 	PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_GRID | PAINT_LEFT );		// Paint
344 
345 	delete[] pStyles;
346 }
347 
348 
349 sal_Bool __EXPORT ScDocShell::Insert( SfxObjectShell &rSource,
350 								sal_uInt16 nSourceIdx1, sal_uInt16 nSourceIdx2, sal_uInt16 nSourceIdx3,
351 								sal_uInt16 &nIdx1, sal_uInt16 &nIdx2, sal_uInt16 &nIdx3, sal_uInt16 &rIdxDeleted )
352 {
353 	sal_Bool bRet = SfxObjectShell::Insert( rSource, nSourceIdx1, nSourceIdx2, nSourceIdx3,
354 											nIdx1, nIdx2, nIdx3, rIdxDeleted );
355 	if (bRet)
356 		lcl_AdjustPool( GetStyleSheetPool() );		// SetItems anpassen
357 
358 	return bRet;
359 }
360 
361 void ScDocShell::UpdateLinks()
362 {
363 	sfx2::LinkManager* pLinkManager = aDocument.GetLinkManager();
364 	ScStrCollection aNames;
365 
366 	// nicht mehr benutzte Links raus
367 
368 	sal_uInt16 nCount = pLinkManager->GetLinks().Count();
369 	for (sal_uInt16 k=nCount; k>0; )
370 	{
371 		--k;
372 		::sfx2::SvBaseLink* pBase = *pLinkManager->GetLinks()[k];
373 		if (pBase->ISA(ScTableLink))
374 		{
375 			ScTableLink* pTabLink = (ScTableLink*)pBase;
376 			if (pTabLink->IsUsed())
377 			{
378 				StrData* pData = new StrData(pTabLink->GetFileName());
379 				if (!aNames.Insert(pData))
380 					delete pData;
381 			}
382 			else		// nicht mehr benutzt -> loeschen
383 			{
384 				pTabLink->SetAddUndo(sal_True);
385 				pLinkManager->Remove(k);
386 			}
387 		}
388 	}
389 
390 
391 	// neue Links eintragen
392 
393 	SCTAB nTabCount = aDocument.GetTableCount();
394 	for (SCTAB i=0; i<nTabCount; i++)
395 		if (aDocument.IsLinked(i))
396 		{
397 			String aDocName = aDocument.GetLinkDoc(i);
398 			String aFltName = aDocument.GetLinkFlt(i);
399 			String aOptions = aDocument.GetLinkOpt(i);
400 			sal_uLong nRefresh	= aDocument.GetLinkRefreshDelay(i);
401 			sal_Bool bThere = sal_False;
402 			for (SCTAB j=0; j<i && !bThere; j++)				// im Dokument mehrfach?
403 				if (aDocument.IsLinked(j)
404 						&& aDocument.GetLinkDoc(j) == aDocName
405 						&& aDocument.GetLinkFlt(j) == aFltName
406 						&& aDocument.GetLinkOpt(j) == aOptions)
407 						// Ignore refresh delay in compare, it should be the
408 						// same for identical links and we don't want dupes
409 						// if it ain't.
410 					bThere = sal_True;
411 
412 			if (!bThere)										// schon als Filter eingetragen?
413 			{
414 				StrData* pData = new StrData(aDocName);
415 				if (!aNames.Insert(pData))
416 				{
417 					delete pData;
418 					bThere = sal_True;
419 				}
420 			}
421 			if (!bThere)
422 			{
423 				ScTableLink* pLink = new ScTableLink( this, aDocName, aFltName, aOptions, nRefresh );
424 				pLink->SetInCreate( sal_True );
425 				pLinkManager->InsertFileLink( *pLink, OBJECT_CLIENT_FILE, aDocName, &aFltName );
426 				pLink->Update();
427 				pLink->SetInCreate( sal_False );
428 			}
429 		}
430 }
431 
432 sal_Bool ScDocShell::ReloadTabLinks()
433 {
434 	sfx2::LinkManager* pLinkManager = aDocument.GetLinkManager();
435 
436 	sal_Bool bAny = sal_False;
437 	sal_uInt16 nCount = pLinkManager->GetLinks().Count();
438 	for (sal_uInt16 i=0; i<nCount; i++ )
439 	{
440         ::sfx2::SvBaseLink* pBase = *pLinkManager->GetLinks()[i];
441 		if (pBase->ISA(ScTableLink))
442 		{
443 			ScTableLink* pTabLink = (ScTableLink*)pBase;
444 //			pTabLink->SetAddUndo(sal_False);		//! Undo's zusammenfassen
445 			pTabLink->SetPaint(sal_False);			//	Paint nur einmal am Ende
446 			pTabLink->Update();
447 			pTabLink->SetPaint(sal_True);
448 //			pTabLink->SetAddUndo(sal_True);
449 			bAny = sal_True;
450 		}
451 	}
452 
453 	if ( bAny )
454 	{
455 		//	Paint nur einmal
456 		PostPaint( ScRange(0,0,0,MAXCOL,MAXROW,MAXTAB),
457 									PAINT_GRID | PAINT_TOP | PAINT_LEFT );
458 
459 		SetDocumentModified();
460 	}
461 
462 	return sal_True;		//! Fehler erkennen
463 }
464 
465 
466