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