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