xref: /AOO41X/main/sc/source/ui/docshell/docsh6.cxx (revision 06fcc9946ad27e93cff9dfbab362ce7c09ccf50b)
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 
SetVisArea(const Rectangle & rVisArea)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 
lcl_SetTopRight(Rectangle & rRect,const Point & rPos)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 
SetVisAreaOrSize(const Rectangle & rVisArea,sal_Bool bModifyStart)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 
IsOle()171 sal_Bool ScDocShell::IsOle()
172 {
173     return (GetCreateMode() == SFX_CREATE_MODE_EMBEDDED);
174 }
175 
UpdateOle(const ScViewData * pViewData,sal_Bool bSnapSize)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 
GetStyleSheetPool()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 
lcl_AdjustPool(SfxStyleSheetBasePool * pStylePool)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 
LoadStyles(SfxObjectShell & rSource)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 
LoadStylesArgs(ScDocShell & rSource,sal_Bool bReplace,sal_Bool bCellStyles,sal_Bool bPageStyles)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 
Insert(SfxObjectShell & rSource,sal_uInt16 nSourceIdx1,sal_uInt16 nSourceIdx2,sal_uInt16 nSourceIdx3,sal_uInt16 & nIdx1,sal_uInt16 & nIdx2,sal_uInt16 & nIdx3,sal_uInt16 & rIdxDeleted)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 
UpdateLinks()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 
ReloadTabLinks()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             // Painting only after Update() makes no sense:
446             // ScTableLink::Refresh() will post a Paint only is bDoPaint is true
447             //pTabLink->SetPaint(sal_False);            //  Paint nur einmal am Ende
448             pTabLink->Update();
449             //pTabLink->SetPaint(sal_True);
450 //          pTabLink->SetAddUndo(sal_True);
451             bAny = sal_True;
452         }
453     }
454 
455     if ( bAny )
456     {
457         //  Paint nur einmal
458         PostPaint( ScRange(0,0,0,MAXCOL,MAXROW,MAXTAB),
459                                     PAINT_GRID | PAINT_TOP | PAINT_LEFT );
460 
461         SetDocumentModified();
462     }
463 
464     return sal_True;        //! Fehler erkennen
465 }
466 
467 
468