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