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 // System - Includes ----------------------------------------------------- 31 32 #include "scitems.hxx" 33 #include <editeng/eeitem.hxx> 34 #include <editeng/svxenum.hxx> 35 #include <svx/algitem.hxx> 36 37 #include <sot/clsids.hxx> 38 #include <unotools/securityoptions.hxx> 39 #include <tools/stream.hxx> 40 #include <tools/string.hxx> 41 #include <tools/urlobj.hxx> 42 #include <vcl/msgbox.hxx> 43 #include <vcl/virdev.hxx> 44 #include <vcl/waitobj.hxx> 45 #include <svtools/ctrltool.hxx> 46 #include <svtools/sfxecode.hxx> 47 #include <svl/zforlist.hxx> 48 #include <svl/PasswordHelper.hxx> 49 #include <sfx2/app.hxx> 50 #include <sfx2/bindings.hxx> 51 #include <sfx2/dinfdlg.hxx> 52 #include <sfx2/docfile.hxx> 53 #include <sfx2/docfilt.hxx> 54 #include <sfx2/fcontnr.hxx> 55 #include <sfx2/evntconf.hxx> 56 #include <sfx2/sfx.hrc> 57 #include <sfx2/objface.hxx> 58 #include <svl/srchitem.hxx> 59 #include <unotools/fltrcfg.hxx> 60 #include <svl/documentlockfile.hxx> 61 #include <svl/sharecontrolfile.hxx> 62 #include <unotools/charclass.hxx> 63 #include <vcl/virdev.hxx> 64 #include "chgtrack.hxx" 65 #include "chgviset.hxx" 66 #include <sfx2/request.hxx> 67 #include <com/sun/star/container/XContentEnumerationAccess.hpp> 68 #include <com/sun/star/document/UpdateDocMode.hpp> 69 #include <com/sun/star/script/vba/VBAEventId.hpp> 70 #include <com/sun/star/script/vba/XVBAEventProcessor.hpp> 71 #include <com/sun/star/sheet/XSpreadsheetView.hpp> 72 #include <com/sun/star/task/XJob.hpp> 73 #include <basic/sbstar.hxx> 74 #include <basic/basmgr.hxx> 75 76 #include "scabstdlg.hxx" //CHINA001 77 #include <sot/formats.hxx> 78 #define SOT_FORMATSTR_ID_STARCALC_30 SOT_FORMATSTR_ID_STARCALC 79 80 // INCLUDE --------------------------------------------------------------- 81 82 #include "cell.hxx" 83 #include "global.hxx" 84 #include "filter.hxx" 85 #include "scmod.hxx" 86 #include "tabvwsh.hxx" 87 #include "docfunc.hxx" 88 #include "imoptdlg.hxx" 89 #include "impex.hxx" 90 #include "scresid.hxx" 91 #include "sc.hrc" 92 #include "globstr.hrc" 93 #include "scerrors.hxx" 94 #include "brdcst.hxx" 95 #include "stlpool.hxx" 96 #include "autostyl.hxx" 97 #include "attrib.hxx" 98 #include "asciiopt.hxx" 99 #include "waitoff.hxx" 100 #include "docpool.hxx" // LoadCompleted 101 #include "progress.hxx" 102 #include "pntlock.hxx" 103 #include "collect.hxx" 104 #include "docuno.hxx" 105 #include "appoptio.hxx" 106 #include "detdata.hxx" 107 #include "printfun.hxx" 108 #include "dociter.hxx" 109 #include "cellform.hxx" 110 #include "chartlis.hxx" 111 #include "hints.hxx" 112 #include "xmlwrap.hxx" 113 #include "drwlayer.hxx" 114 #include "refreshtimer.hxx" 115 #include "dbcolect.hxx" 116 #include "scextopt.hxx" 117 #include "compiler.hxx" 118 #include "cfgids.hxx" 119 #include "warnpassword.hxx" 120 #include "optsolver.hxx" 121 #include "sheetdata.hxx" 122 #include "tabprotection.hxx" 123 #include "dpobject.hxx" 124 125 #include "docsh.hxx" 126 #include "docshimp.hxx" 127 #include <rtl/logfile.hxx> 128 129 #include <comphelper/processfactory.hxx> 130 #include "uiitems.hxx" 131 #include "cellsuno.hxx" 132 133 using namespace com::sun::star; 134 using ::rtl::OUString; 135 using ::rtl::OUStringBuffer; 136 137 // STATIC DATA ----------------------------------------------------------- 138 139 // Stream-Namen im Storage 140 141 const sal_Char __FAR_DATA ScDocShell::pStarCalcDoc[] = STRING_SCSTREAM; // "StarCalcDocument" 142 const sal_Char __FAR_DATA ScDocShell::pStyleName[] = "SfxStyleSheets"; 143 144 // Filter-Namen (wie in sclib.cxx) 145 146 static const sal_Char __FAR_DATA pFilterSc50[] = "StarCalc 5.0"; 147 //static const sal_Char __FAR_DATA pFilterSc50Temp[] = "StarCalc 5.0 Vorlage/Template"; 148 static const sal_Char __FAR_DATA pFilterSc40[] = "StarCalc 4.0"; 149 //static const sal_Char __FAR_DATA pFilterSc40Temp[] = "StarCalc 4.0 Vorlage/Template"; 150 static const sal_Char __FAR_DATA pFilterSc30[] = "StarCalc 3.0"; 151 //static const sal_Char __FAR_DATA pFilterSc30Temp[] = "StarCalc 3.0 Vorlage/Template"; 152 static const sal_Char __FAR_DATA pFilterSc10[] = "StarCalc 1.0"; 153 static const sal_Char __FAR_DATA pFilterXML[] = "StarOffice XML (Calc)"; 154 static const sal_Char __FAR_DATA pFilterAscii[] = "Text - txt - csv (StarCalc)"; 155 static const sal_Char __FAR_DATA pFilterLotus[] = "Lotus"; 156 static const sal_Char __FAR_DATA pFilterQPro6[] = "Quattro Pro 6.0"; 157 static const sal_Char __FAR_DATA pFilterExcel4[] = "MS Excel 4.0"; 158 static const sal_Char __FAR_DATA pFilterEx4Temp[] = "MS Excel 4.0 Vorlage/Template"; 159 static const sal_Char __FAR_DATA pFilterExcel5[] = "MS Excel 5.0/95"; 160 static const sal_Char __FAR_DATA pFilterEx5Temp[] = "MS Excel 5.0/95 Vorlage/Template"; 161 static const sal_Char __FAR_DATA pFilterExcel95[] = "MS Excel 95"; 162 static const sal_Char __FAR_DATA pFilterEx95Temp[] = "MS Excel 95 Vorlage/Template"; 163 static const sal_Char __FAR_DATA pFilterExcel97[] = "MS Excel 97"; 164 static const sal_Char __FAR_DATA pFilterEx97Temp[] = "MS Excel 97 Vorlage/Template"; 165 static const sal_Char __FAR_DATA pFilterEx07Xml[] = "MS Excel 2007 XML"; 166 static const sal_Char __FAR_DATA pFilterDBase[] = "dBase"; 167 static const sal_Char __FAR_DATA pFilterDif[] = "DIF"; 168 static const sal_Char __FAR_DATA pFilterSylk[] = "SYLK"; 169 static const sal_Char __FAR_DATA pFilterHtml[] = "HTML (StarCalc)"; 170 static const sal_Char __FAR_DATA pFilterHtmlWebQ[] = "calc_HTML_WebQuery"; 171 static const sal_Char __FAR_DATA pFilterRtf[] = "Rich Text Format (StarCalc)"; 172 173 //---------------------------------------------------------------------- 174 175 #define ScDocShell 176 #include "scslots.hxx" 177 178 179 SFX_IMPL_INTERFACE(ScDocShell,SfxObjectShell, ScResId(SCSTR_DOCSHELL)) 180 { 181 SFX_CHILDWINDOW_REGISTRATION( SID_HYPERLINK_INSERT ); 182 } 183 184 // GlobalName der aktuellen Version: 185 SFX_IMPL_OBJECTFACTORY( ScDocShell, SvGlobalName(SO3_SC_CLASSID), SFXOBJECTSHELL_STD_NORMAL, "scalc" ) 186 187 TYPEINIT1( ScDocShell, SfxObjectShell ); // SfxInPlaceObject: kein Type-Info ? 188 189 //------------------------------------------------------------------ 190 191 void __EXPORT ScDocShell::FillClass( SvGlobalName* pClassName, 192 sal_uInt32* pFormat, 193 String* /* pAppName */, 194 String* pFullTypeName, 195 String* pShortTypeName, 196 sal_Int32 nFileFormat, 197 sal_Bool bTemplate /* = sal_False */) const 198 { 199 if ( nFileFormat == SOFFICE_FILEFORMAT_60 ) 200 { 201 *pClassName = SvGlobalName( SO3_SC_CLASSID_60 ); 202 *pFormat = SOT_FORMATSTR_ID_STARCALC_60; 203 *pFullTypeName = String( ScResId( SCSTR_LONG_SCDOC_NAME ) ); 204 *pShortTypeName = String( ScResId( SCSTR_SHORT_SCDOC_NAME ) ); 205 } 206 else if ( nFileFormat == SOFFICE_FILEFORMAT_8 ) 207 { 208 *pClassName = SvGlobalName( SO3_SC_CLASSID_60 ); 209 *pFormat = bTemplate ? SOT_FORMATSTR_ID_STARCALC_8_TEMPLATE : SOT_FORMATSTR_ID_STARCALC_8; 210 *pFullTypeName = String( RTL_CONSTASCII_USTRINGPARAM("calc8") ); 211 *pShortTypeName = String( ScResId( SCSTR_SHORT_SCDOC_NAME ) ); 212 } 213 else 214 { 215 DBG_ERROR("wat fuer ne Version?"); 216 } 217 } 218 219 //------------------------------------------------------------------ 220 221 void ScDocShell::DoEnterHandler() 222 { 223 ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell(); 224 if (pViewSh) 225 if (pViewSh->GetViewData()->GetDocShell() == this) 226 SC_MOD()->InputEnterHandler(); 227 } 228 229 //------------------------------------------------------------------ 230 231 SCTAB ScDocShell::GetSaveTab() 232 { 233 SCTAB nTab = 0; 234 ScTabViewShell* pSh = GetBestViewShell(); 235 if (pSh) 236 { 237 const ScMarkData& rMark = pSh->GetViewData()->GetMarkData(); 238 for ( nTab = 0; nTab <= MAXTAB; nTab++ ) // erste markierte Tabelle 239 if ( rMark.GetTableSelect( nTab ) ) 240 break; 241 } 242 return nTab; 243 } 244 245 sal_uInt16 ScDocShell::GetHiddenInformationState( sal_uInt16 nStates ) 246 { 247 // get global state like HIDDENINFORMATION_DOCUMENTVERSIONS 248 sal_uInt16 nState = SfxObjectShell::GetHiddenInformationState( nStates ); 249 250 if ( nStates & HIDDENINFORMATION_RECORDEDCHANGES ) 251 { 252 if ( aDocument.GetChangeTrack() && aDocument.GetChangeTrack()->GetFirst() ) 253 nState |= HIDDENINFORMATION_RECORDEDCHANGES; 254 } 255 if ( nStates & HIDDENINFORMATION_NOTES ) 256 { 257 SCTAB nTableCount = aDocument.GetTableCount(); 258 SCTAB nTable = 0; 259 sal_Bool bFound(sal_False); 260 while ( nTable < nTableCount && !bFound ) 261 { 262 ScCellIterator aCellIter( &aDocument, 0,0, nTable, MAXCOL,MAXROW, nTable ); 263 for( ScBaseCell* pCell = aCellIter.GetFirst(); pCell && !bFound; pCell = aCellIter.GetNext() ) 264 if (pCell->HasNote()) 265 bFound = sal_True; 266 nTable++; 267 } 268 269 if (bFound) 270 nState |= HIDDENINFORMATION_NOTES; 271 } 272 273 return nState; 274 } 275 276 void ScDocShell::BeforeXMLLoading() 277 { 278 aDocument.DisableIdle( sal_True ); 279 280 // prevent unnecessary broadcasts and updates 281 DBG_ASSERT(pModificator == NULL, "The Modificator should not exist"); 282 pModificator = new ScDocShellModificator( *this ); 283 284 aDocument.SetImportingXML( sal_True ); 285 aDocument.EnableExecuteLink( false ); // #i101304# to be safe, prevent nested loading from external references 286 aDocument.EnableUndo( sal_False ); 287 // prevent unnecessary broadcasts and "half way listeners" 288 aDocument.SetInsertingFromOtherDoc( sal_True ); 289 290 if (GetCreateMode() != SFX_CREATE_MODE_ORGANIZER) 291 ScColumn::bDoubleAlloc = sal_True; 292 } 293 294 void ScDocShell::AfterXMLLoading(sal_Bool bRet) 295 { 296 if (GetCreateMode() != SFX_CREATE_MODE_ORGANIZER) 297 { 298 UpdateLinks(); 299 // don't prevent establishing of listeners anymore 300 aDocument.SetInsertingFromOtherDoc( sal_False ); 301 if ( bRet ) 302 { 303 ScChartListenerCollection* pChartListener = aDocument.GetChartListenerCollection(); 304 if (pChartListener) 305 pChartListener->UpdateDirtyCharts(); 306 307 // #95582#; set the table names of linked tables to the new path 308 SCTAB nTabCount = aDocument.GetTableCount(); 309 for (SCTAB i = 0; i < nTabCount; ++i) 310 { 311 if (aDocument.IsLinked( i )) 312 { 313 String aName; 314 aDocument.GetName(i, aName); 315 String aLinkTabName = aDocument.GetLinkTab(i); 316 xub_StrLen nLinkTabNameLength = aLinkTabName.Len(); 317 xub_StrLen nNameLength = aName.Len(); 318 if (nLinkTabNameLength < nNameLength) 319 { 320 321 // remove the quottes on begin and end of the docname and restore the escaped quotes 322 const sal_Unicode* pNameBuffer = aName.GetBuffer(); 323 if ( *pNameBuffer == '\'' && // all docnames have to have a ' character on the first pos 324 ScGlobal::UnicodeStrChr( pNameBuffer, SC_COMPILER_FILE_TAB_SEP ) ) 325 { 326 rtl::OUStringBuffer aDocURLBuffer; 327 sal_Bool bQuote = sal_True; // Dokumentenname ist immer quoted 328 ++pNameBuffer; 329 while ( bQuote && *pNameBuffer ) 330 { 331 if ( *pNameBuffer == '\'' && *(pNameBuffer-1) != '\\' ) 332 bQuote = sal_False; 333 else if( !(*pNameBuffer == '\\' && *(pNameBuffer+1) == '\'') ) 334 aDocURLBuffer.append(*pNameBuffer); // falls escaped Quote: nur Quote in den Namen 335 ++pNameBuffer; 336 } 337 338 339 if( *pNameBuffer == SC_COMPILER_FILE_TAB_SEP ) // after the last quote of the docname should be the # char 340 { 341 xub_StrLen nIndex = nNameLength - nLinkTabNameLength; 342 INetURLObject aINetURLObject(aDocURLBuffer.makeStringAndClear()); 343 if( aName.Equals(aLinkTabName, nIndex, nLinkTabNameLength) && 344 (aName.GetChar(nIndex - 1) == '#') && // before the table name should be the # char 345 !aINetURLObject.HasError()) // the docname should be a valid URL 346 { 347 aName = ScGlobal::GetDocTabName( aDocument.GetLinkDoc( i ), aDocument.GetLinkTab( i ) ); 348 aDocument.RenameTab(i, aName, sal_True, sal_True); 349 } 350 // else; nothing has to happen, because it is a user given name 351 } 352 // else; nothing has to happen, because it is a user given name 353 } 354 // else; nothing has to happen, because it is a user given name 355 } 356 // else; nothing has to happen, because it is a user given name 357 } 358 } 359 360 // #i94570# DataPilot table names have to be unique, or the tables can't be accessed by API. 361 // If no name (or an invalid name, skipped in ScXMLDataPilotTableContext::EndElement) was set, create a new name. 362 ScDPCollection* pDPCollection = aDocument.GetDPCollection(); 363 if ( pDPCollection ) 364 { 365 sal_uInt16 nDPCount = pDPCollection->GetCount(); 366 for (sal_uInt16 nDP=0; nDP<nDPCount; nDP++) 367 { 368 ScDPObject* pDPObj = (*pDPCollection)[nDP]; 369 if ( !pDPObj->GetName().Len() ) 370 pDPObj->SetName( pDPCollection->CreateNewName() ); 371 } 372 } 373 } 374 ScColumn::bDoubleAlloc = sal_False; 375 } 376 else 377 aDocument.SetInsertingFromOtherDoc( sal_False ); 378 379 aDocument.SetImportingXML( sal_False ); 380 aDocument.EnableExecuteLink( true ); 381 aDocument.EnableUndo( sal_True ); 382 bIsEmpty = sal_False; 383 384 if (pModificator) 385 { 386 delete pModificator; 387 pModificator = NULL; 388 } 389 else 390 { 391 DBG_ERROR("The Modificator should exist"); 392 } 393 394 aDocument.DisableIdle( sal_False ); 395 } 396 397 sal_Bool ScDocShell::LoadXML( SfxMedium* pLoadMedium, const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStor ) 398 { 399 RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "sb99857", "ScDocShell::LoadXML" ); 400 401 // MacroCallMode is no longer needed, state is kept in SfxObjectShell now 402 403 // no Seek(0) here - always loading from storage, GetInStream must not be called 404 405 BeforeXMLLoading(); 406 407 // #i62677# BeforeXMLLoading is also called from ScXMLImport::startDocument when invoked 408 // from an external component. The XMLFromWrapper flag is only set here, when called 409 // through ScDocShell. 410 aDocument.SetXMLFromWrapper( sal_True ); 411 412 ScXMLImportWrapper aImport( aDocument, pLoadMedium, xStor ); 413 414 sal_Bool bRet(sal_False); 415 ErrCode nError = ERRCODE_NONE; 416 if (GetCreateMode() != SFX_CREATE_MODE_ORGANIZER) 417 bRet = aImport.Import(sal_False, nError); 418 else 419 bRet = aImport.Import(sal_True, nError); 420 421 if ( nError ) 422 pLoadMedium->SetError( nError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); 423 424 aDocument.SetXMLFromWrapper( sal_False ); 425 AfterXMLLoading(bRet); 426 427 //! row heights... 428 429 return bRet; 430 } 431 432 sal_Bool ScDocShell::SaveXML( SfxMedium* pSaveMedium, const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStor ) 433 { 434 RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "sb99857", "ScDocShell::SaveXML" ); 435 436 aDocument.DisableIdle( sal_True ); 437 438 ScXMLImportWrapper aImport( aDocument, pSaveMedium, xStor ); 439 sal_Bool bRet(sal_False); 440 if (GetCreateMode() != SFX_CREATE_MODE_ORGANIZER) 441 bRet = aImport.Export(sal_False); 442 else 443 bRet = aImport.Export(sal_True); 444 445 aDocument.DisableIdle( sal_False ); 446 447 return bRet; 448 } 449 450 sal_Bool __EXPORT ScDocShell::Load( SfxMedium& rMedium ) 451 { 452 RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::Load" ); 453 454 ScRefreshTimerProtector( aDocument.GetRefreshTimerControlAddress() ); 455 456 // only the latin script language is loaded 457 // -> initialize the others from options (before loading) 458 InitOptions(true); 459 460 GetUndoManager()->Clear(); 461 462 sal_Bool bRet = SfxObjectShell::Load( rMedium ); 463 if( bRet ) 464 { 465 if (GetMedium()) 466 { 467 SFX_ITEMSET_ARG( rMedium.GetItemSet(), pUpdateDocItem, SfxUInt16Item, SID_UPDATEDOCMODE, sal_False); 468 nCanUpdate = pUpdateDocItem ? pUpdateDocItem->GetValue() : com::sun::star::document::UpdateDocMode::NO_UPDATE; 469 } 470 471 { 472 // prepare a valid document for XML filter 473 // (for ConvertFrom, InitNew is called before) 474 aDocument.MakeTable(0); 475 aDocument.GetStyleSheetPool()->CreateStandardStyles(); 476 aDocument.UpdStlShtPtrsFrmNms(); 477 478 bRet = LoadXML( &rMedium, NULL ); 479 } 480 } 481 482 if (!bRet && !rMedium.GetError()) 483 rMedium.SetError( SVSTREAM_FILEFORMAT_ERROR, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); 484 485 if (rMedium.GetError()) 486 SetError( rMedium.GetError(), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); 487 488 InitItems(); 489 CalcOutputFactor(); 490 491 // #73762# invalidate eventually temporary table areas 492 if ( bRet ) 493 aDocument.InvalidateTableArea(); 494 495 bIsEmpty = sal_False; 496 FinishedLoading( SFX_LOADED_MAINDOCUMENT | SFX_LOADED_IMAGES ); 497 return bRet; 498 } 499 500 void __EXPORT ScDocShell::Notify( SfxBroadcaster&, const SfxHint& rHint ) 501 { 502 if (rHint.ISA(ScTablesHint) ) 503 { 504 const ScTablesHint& rScHint = static_cast< const ScTablesHint& >( rHint ); 505 if (rScHint.GetId() == SC_TAB_INSERTED) 506 { 507 uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents = aDocument.GetVbaEventProcessor(); 508 if ( xVbaEvents.is() ) try 509 { 510 uno::Sequence< uno::Any > aArgs( 1 ); 511 aArgs[0] <<= rScHint.GetTab1(); 512 xVbaEvents->processVbaEvent( script::vba::VBAEventId::WORKBOOK_NEWSHEET, aArgs ); 513 } 514 catch( uno::Exception& ) 515 { 516 } 517 } 518 } 519 520 if (rHint.ISA(SfxSimpleHint)) // ohne Parameter 521 { 522 sal_uLong nSlot = ((const SfxSimpleHint&)rHint).GetId(); 523 switch ( nSlot ) 524 { 525 case SFX_HINT_TITLECHANGED: 526 aDocument.SetName( SfxShell::GetName() ); 527 // RegisterNewTargetNames gibts nicht mehr 528 SFX_APP()->Broadcast(SfxSimpleHint( SC_HINT_DOCNAME_CHANGED )); // Navigator 529 break; 530 } 531 } 532 else if (rHint.ISA(SfxStyleSheetHint)) // Vorlagen geaendert 533 NotifyStyle((const SfxStyleSheetHint&) rHint); 534 else if (rHint.ISA(ScAutoStyleHint)) 535 { 536 //! direct call for AutoStyles 537 538 // this is called synchronously from ScInterpreter::ScStyle, 539 // modifying the document must be asynchronous 540 // (handled by AddInitial) 541 542 ScAutoStyleHint& rStlHint = (ScAutoStyleHint&)rHint; 543 ScRange aRange = rStlHint.GetRange(); 544 String aName1 = rStlHint.GetStyle1(); 545 String aName2 = rStlHint.GetStyle2(); 546 sal_uInt32 nTimeout = rStlHint.GetTimeout(); 547 548 if (!pAutoStyleList) 549 pAutoStyleList = new ScAutoStyleList(this); 550 pAutoStyleList->AddInitial( aRange, aName1, nTimeout, aName2 ); 551 } 552 else if ( rHint.ISA( SfxEventHint ) ) 553 { 554 sal_uLong nEventId = ((SfxEventHint&)rHint).GetEventId(); 555 switch ( nEventId ) 556 { 557 case SFX_EVENT_LOADFINISHED: 558 { 559 // the readonly documents should not be opened in shared mode 560 if ( HasSharedXMLFlagSet() && !SC_MOD()->IsInSharedDocLoading() && !IsReadOnly() ) 561 { 562 if ( SwitchToShared( sal_True, sal_False ) ) 563 { 564 ScViewData* pViewData = GetViewData(); 565 ScTabView* pTabView = ( pViewData ? dynamic_cast< ScTabView* >( pViewData->GetView() ) : NULL ); 566 if ( pTabView ) 567 { 568 pTabView->UpdateLayerLocks(); 569 } 570 } 571 else 572 { 573 // switching to shared mode has failed, the document should be opened readonly 574 // TODO/LATER: And error message should be shown here probably 575 SetReadOnlyUI( sal_True ); 576 } 577 } 578 } 579 break; 580 case SFX_EVENT_VIEWCREATED: 581 { 582 if ( IsDocShared() && !SC_MOD()->IsInSharedDocLoading() ) 583 { 584 ScAppOptions aAppOptions = SC_MOD()->GetAppOptions(); 585 if ( aAppOptions.GetShowSharedDocumentWarning() ) 586 { 587 WarningBox aBox( GetActiveDialogParent(), WinBits( WB_OK ), 588 ScGlobal::GetRscString( STR_SHARED_DOC_WARNING ) ); 589 aBox.SetDefaultCheckBoxText(); 590 aBox.Execute(); 591 sal_Bool bChecked = aBox.GetCheckBoxState(); 592 if ( bChecked ) 593 { 594 aAppOptions.SetShowSharedDocumentWarning( !bChecked ); 595 SC_MOD()->SetAppOptions( aAppOptions ); 596 } 597 } 598 } 599 600 try 601 { 602 uno::Reference< uno::XComponentContext > xContext; 603 uno::Reference< lang::XMultiServiceFactory > xServiceManager = ::comphelper::getProcessServiceFactory(); 604 uno::Reference< beans::XPropertySet > xProp( xServiceManager, uno::UNO_QUERY_THROW ); 605 xProp->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ) ) ) >>= xContext; 606 if ( xContext.is() ) 607 { 608 uno::Reference< container::XContentEnumerationAccess > xEnumAccess( xServiceManager, uno::UNO_QUERY_THROW ); 609 uno::Reference< container::XEnumeration> xEnum = xEnumAccess->createContentEnumeration( 610 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.SpreadsheetDocumentJob" ) ) ); 611 if ( xEnum.is() ) 612 { 613 while ( xEnum->hasMoreElements() ) 614 { 615 uno::Any aAny = xEnum->nextElement(); 616 uno::Reference< lang::XSingleComponentFactory > xFactory; 617 aAny >>= xFactory; 618 if ( xFactory.is() ) 619 { 620 uno::Reference< task::XJob > xJob( xFactory->createInstanceWithContext( xContext ), uno::UNO_QUERY_THROW ); 621 uno::Sequence< beans::NamedValue > aArgsForJob(1); 622 ScViewData* pViewData = GetViewData(); 623 SfxViewShell* pViewShell = ( pViewData ? pViewData->GetViewShell() : NULL ); 624 SfxViewFrame* pViewFrame = ( pViewShell ? pViewShell->GetViewFrame() : NULL ); 625 SfxFrame* pFrame = ( pViewFrame ? &pViewFrame->GetFrame() : NULL ); 626 uno::Reference< frame::XController > xController = ( pFrame ? pFrame->GetController() : 0 ); 627 uno::Reference< sheet::XSpreadsheetView > xSpreadsheetView( xController, uno::UNO_QUERY_THROW ); 628 aArgsForJob[0] = beans::NamedValue( ::rtl::OUString::createFromAscii( "SpreadsheetView" ), 629 uno::makeAny( xSpreadsheetView ) ); 630 xJob->execute( aArgsForJob ); 631 } 632 } 633 } 634 } 635 } 636 catch ( uno::Exception & ) 637 { 638 } 639 } 640 break; 641 case SFX_EVENT_SAVEDOC: 642 { 643 if ( IsDocShared() && !SC_MOD()->IsInSharedDocSaving() ) 644 { 645 bool bSuccess = false; 646 bool bRetry = true; 647 while ( bRetry ) 648 { 649 bRetry = false; 650 uno::Reference< frame::XModel > xModel; 651 try 652 { 653 // load shared file 654 xModel.set( LoadSharedDocument(), uno::UNO_QUERY_THROW ); 655 uno::Reference< util::XCloseable > xCloseable( xModel, uno::UNO_QUERY_THROW ); 656 657 // check if shared flag is set in shared file 658 bool bShared = false; 659 ScModelObj* pDocObj = ScModelObj::getImplementation( xModel ); 660 ScDocShell* pSharedDocShell = ( pDocObj ? dynamic_cast< ScDocShell* >( pDocObj->GetObjectShell() ) : NULL ); 661 if ( pSharedDocShell ) 662 { 663 bShared = pSharedDocShell->HasSharedXMLFlagSet(); 664 } 665 666 // #i87870# check if shared status was disabled and enabled again 667 bool bOwnEntry = false; 668 bool bEntriesNotAccessible = false; 669 try 670 { 671 ::svt::ShareControlFile aControlFile( GetSharedFileURL() ); 672 bOwnEntry = aControlFile.HasOwnEntry(); 673 } 674 catch ( uno::Exception& ) 675 { 676 bEntriesNotAccessible = true; 677 } 678 679 if ( bShared && bOwnEntry ) 680 { 681 uno::Reference< frame::XStorable > xStorable( xModel, uno::UNO_QUERY_THROW ); 682 683 if ( xStorable->isReadonly() ) 684 { 685 xCloseable->close( sal_True ); 686 687 String aUserName( ScGlobal::GetRscString( STR_UNKNOWN_USER ) ); 688 bool bNoLockAccess = false; 689 try 690 { 691 ::svt::DocumentLockFile aLockFile( GetSharedFileURL() ); 692 uno::Sequence< ::rtl::OUString > aData = aLockFile.GetLockData(); 693 if ( aData.getLength() > LOCKFILE_SYSUSERNAME_ID ) 694 { 695 if ( aData[LOCKFILE_OOOUSERNAME_ID].getLength() > 0 ) 696 { 697 aUserName = aData[LOCKFILE_OOOUSERNAME_ID]; 698 } 699 else if ( aData[LOCKFILE_SYSUSERNAME_ID].getLength() > 0 ) 700 { 701 aUserName = aData[LOCKFILE_SYSUSERNAME_ID]; 702 } 703 } 704 } 705 catch ( uno::Exception& ) 706 { 707 bNoLockAccess = true; 708 } 709 710 if ( bNoLockAccess ) 711 { 712 // TODO/LATER: in future an error regarding impossibility to open file for writing could be shown 713 ErrorHandler::HandleError( ERRCODE_IO_GENERAL ); 714 } 715 else 716 { 717 String aMessage( ScGlobal::GetRscString( STR_FILE_LOCKED_SAVE_LATER ) ); 718 aMessage.SearchAndReplaceAscii( "%1", aUserName ); 719 720 WarningBox aBox( GetActiveDialogParent(), WinBits( WB_RETRY_CANCEL | WB_DEF_RETRY ), aMessage ); 721 if ( aBox.Execute() == RET_RETRY ) 722 { 723 bRetry = true; 724 } 725 } 726 } 727 else 728 { 729 // merge changes from shared file into temp file 730 bool bSaveToShared = false; 731 if ( pSharedDocShell ) 732 { 733 bSaveToShared = MergeSharedDocument( pSharedDocShell ); 734 } 735 736 // close shared file 737 xCloseable->close( sal_True ); 738 739 // TODO: keep file lock on shared file 740 741 // store to shared file 742 if ( bSaveToShared ) 743 { 744 bool bChangedViewSettings = false; 745 ScChangeViewSettings* pChangeViewSet = aDocument.GetChangeViewSettings(); 746 if ( pChangeViewSet && pChangeViewSet->ShowChanges() ) 747 { 748 pChangeViewSet->SetShowChanges( sal_False ); 749 pChangeViewSet->SetShowAccepted( sal_False ); 750 aDocument.SetChangeViewSettings( *pChangeViewSet ); 751 bChangedViewSettings = true; 752 } 753 754 uno::Reference< frame::XStorable > xStor( GetModel(), uno::UNO_QUERY_THROW ); 755 // TODO/LATER: More entries from the MediaDescriptor might be interesting for the merge 756 uno::Sequence< beans::PropertyValue > aValues(1); 757 aValues[0].Name = ::rtl::OUString::createFromAscii( "FilterName" ); 758 aValues[0].Value <<= ::rtl::OUString( GetMedium()->GetFilter()->GetFilterName() ); 759 760 SFX_ITEMSET_ARG( GetMedium()->GetItemSet(), pPasswordItem, SfxStringItem, SID_PASSWORD, sal_False); 761 if ( pPasswordItem && pPasswordItem->GetValue().Len() ) 762 { 763 aValues.realloc( 2 ); 764 aValues[1].Name = ::rtl::OUString::createFromAscii( "Password" ); 765 aValues[1].Value <<= ::rtl::OUString( pPasswordItem->GetValue() ); 766 } 767 768 SC_MOD()->SetInSharedDocSaving( true ); 769 xStor->storeToURL( GetSharedFileURL(), aValues ); 770 SC_MOD()->SetInSharedDocSaving( false ); 771 772 if ( bChangedViewSettings ) 773 { 774 pChangeViewSet->SetShowChanges( sal_True ); 775 pChangeViewSet->SetShowAccepted( sal_True ); 776 aDocument.SetChangeViewSettings( *pChangeViewSet ); 777 } 778 } 779 780 bSuccess = true; 781 GetUndoManager()->Clear(); 782 } 783 } 784 else 785 { 786 xCloseable->close( sal_True ); 787 788 if ( bEntriesNotAccessible ) 789 { 790 // TODO/LATER: in future an error regarding impossibility to write to share control file could be shown 791 ErrorHandler::HandleError( ERRCODE_IO_GENERAL ); 792 } 793 else 794 { 795 WarningBox aBox( GetActiveDialogParent(), WinBits( WB_OK ), 796 ScGlobal::GetRscString( STR_DOC_NOLONGERSHARED ) ); 797 aBox.Execute(); 798 799 SfxBindings* pBindings = GetViewBindings(); 800 if ( pBindings ) 801 { 802 pBindings->ExecuteSynchron( SID_SAVEASDOC ); 803 } 804 } 805 } 806 } 807 catch ( uno::Exception& ) 808 { 809 DBG_ERROR( "SFX_EVENT_SAVEDOC: caught exception\n" ); 810 SC_MOD()->SetInSharedDocSaving( false ); 811 812 try 813 { 814 uno::Reference< util::XCloseable > xClose( xModel, uno::UNO_QUERY_THROW ); 815 xClose->close( sal_True ); 816 } 817 catch ( uno::Exception& ) 818 { 819 } 820 } 821 } 822 823 if ( !bSuccess ) 824 SetError( ERRCODE_IO_ABORT, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); // this error code will produce no error message, but will break the further saving process 825 } 826 if (pSheetSaveData) 827 pSheetSaveData->SetInSupportedSave(true); 828 } 829 break; 830 case SFX_EVENT_SAVEASDOC: 831 case SFX_EVENT_SAVETODOC: 832 // #i108978# If no event is sent before saving, there will also be no "...DONE" event, 833 // and SAVE/SAVEAS can't be distinguished from SAVETO. So stream copying is only enabled 834 // if there is a SAVE/SAVEAS/SAVETO event first. 835 if (pSheetSaveData) 836 pSheetSaveData->SetInSupportedSave(true); 837 break; 838 case SFX_EVENT_SAVEDOCDONE: 839 { 840 if ( IsDocShared() && !SC_MOD()->IsInSharedDocSaving() ) 841 { 842 } 843 UseSheetSaveEntries(); // use positions from saved file for next saving 844 if (pSheetSaveData) 845 pSheetSaveData->SetInSupportedSave(false); 846 } 847 break; 848 case SFX_EVENT_SAVEASDOCDONE: 849 // new positions are used after "save" and "save as", but not "save to" 850 UseSheetSaveEntries(); // use positions from saved file for next saving 851 if (pSheetSaveData) 852 pSheetSaveData->SetInSupportedSave(false); 853 break; 854 case SFX_EVENT_SAVETODOCDONE: 855 // only reset the flag, don't use the new positions 856 if (pSheetSaveData) 857 pSheetSaveData->SetInSupportedSave(false); 858 break; 859 default: 860 { 861 } 862 break; 863 } 864 } 865 } 866 867 // Inhalte fuer Organizer laden 868 869 870 sal_Bool __EXPORT ScDocShell::LoadFrom( SfxMedium& rMedium ) 871 { 872 RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::LoadFrom" ); 873 874 ScRefreshTimerProtector( aDocument.GetRefreshTimerControlAddress() ); 875 876 WaitObject aWait( GetActiveDialogParent() ); 877 878 sal_Bool bRet = sal_False; 879 880 if (GetMedium()) 881 { 882 SFX_ITEMSET_ARG( rMedium.GetItemSet(), pUpdateDocItem, SfxUInt16Item, SID_UPDATEDOCMODE, sal_False); 883 nCanUpdate = pUpdateDocItem ? pUpdateDocItem->GetValue() : com::sun::star::document::UpdateDocMode::NO_UPDATE; 884 } 885 886 // until loading/saving only the styles in XML is implemented, 887 // load the whole file 888 bRet = LoadXML( &rMedium, NULL ); 889 InitItems(); 890 891 SfxObjectShell::LoadFrom( rMedium ); 892 893 return bRet; 894 } 895 896 static void lcl_parseHtmlFilterOption(const OUString& rOption, LanguageType& rLang, bool& rDateConvert) 897 { 898 OUStringBuffer aBuf; 899 OUString aTokens[2]; 900 sal_Int32 n = rOption.getLength(); 901 const sal_Unicode* p = rOption.getStr(); 902 sal_Int32 nTokenId = 0; 903 for (sal_Int32 i = 0; i < n; ++i) 904 { 905 const sal_Unicode c = p[i]; 906 if (c == sal_Unicode(' ')) 907 { 908 if (aBuf.getLength()) 909 aTokens[nTokenId++] = aBuf.makeStringAndClear(); 910 } 911 else 912 aBuf.append(c); 913 914 if (nTokenId >= 2) 915 break; 916 } 917 918 if (aBuf.getLength()) 919 aTokens[nTokenId] = aBuf.makeStringAndClear(); 920 921 rLang = static_cast<LanguageType>(aTokens[0].toInt32()); 922 rDateConvert = static_cast<bool>(aTokens[1].toInt32()); 923 } 924 925 namespace { 926 927 class LoadMediumGuard 928 { 929 public: 930 explicit LoadMediumGuard(ScDocument* pDoc) : 931 mpDoc(pDoc) 932 { 933 mpDoc->SetLoadingMedium(true); 934 } 935 936 ~LoadMediumGuard() 937 { 938 mpDoc->SetLoadingMedium(false); 939 } 940 private: 941 ScDocument* mpDoc; 942 }; 943 944 } 945 946 sal_Bool __EXPORT ScDocShell::ConvertFrom( SfxMedium& rMedium ) 947 { 948 RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::ConvertFrom" ); 949 950 LoadMediumGuard aLoadGuard(&aDocument); 951 952 sal_Bool bRet = sal_False; // sal_False heisst Benutzerabbruch !! 953 // bei Fehler: Fehler am Stream setzen!! 954 955 ScRefreshTimerProtector( aDocument.GetRefreshTimerControlAddress() ); 956 957 GetUndoManager()->Clear(); 958 959 // ob nach dem Import optimale Spaltenbreiten gesetzt werden sollen 960 sal_Bool bSetColWidths = sal_False; 961 sal_Bool bSetSimpleTextColWidths = sal_False; 962 sal_Bool bSimpleColWidth[MAXCOLCOUNT]; 963 memset( bSimpleColWidth, 1, (MAXCOLCOUNT) * sizeof(sal_Bool) ); 964 ScRange aColWidthRange; 965 // ob nach dem Import optimale Zeilenhoehen gesetzt werden sollen 966 sal_Bool bSetRowHeights = sal_False; 967 968 aConvFilterName.Erase(); //@ #BugId 54198 969 970 // Alle Filter brauchen die komplette Datei am Stueck (nicht asynchron), 971 // darum vorher per CreateFileStream dafuer sorgen, dass die komplette 972 // Datei uebertragen wird. 973 rMedium.GetPhysicalName(); //! CreateFileStream direkt rufen, wenn verfuegbar 974 975 SFX_ITEMSET_ARG( rMedium.GetItemSet(), pUpdateDocItem, SfxUInt16Item, SID_UPDATEDOCMODE, sal_False); 976 nCanUpdate = pUpdateDocItem ? pUpdateDocItem->GetValue() : com::sun::star::document::UpdateDocMode::NO_UPDATE; 977 978 const SfxFilter* pFilter = rMedium.GetFilter(); 979 if (pFilter) 980 { 981 String aFltName = pFilter->GetFilterName(); 982 983 aConvFilterName=aFltName; //@ #BugId 54198 984 985 sal_Bool bCalc3 = ( aFltName.EqualsAscii(pFilterSc30) ); 986 sal_Bool bCalc4 = ( aFltName.EqualsAscii(pFilterSc40) ); 987 if (!bCalc3 && !bCalc4) 988 aDocument.SetInsertingFromOtherDoc( sal_True ); 989 990 if (aFltName.EqualsAscii(pFilterXML)) 991 bRet = LoadXML( &rMedium, NULL ); 992 else if (aFltName.EqualsAscii(pFilterSc10)) 993 { 994 SvStream* pStream = rMedium.GetInStream(); 995 if (pStream) 996 { 997 FltError eError = ScFormatFilter::Get().ScImportStarCalc10( *pStream, &aDocument ); 998 if (eError != eERR_OK) 999 { 1000 if (!GetError()) 1001 SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) )); 1002 } 1003 else 1004 bRet = sal_True; 1005 } 1006 } 1007 else if (aFltName.EqualsAscii(pFilterLotus)) 1008 { 1009 String sItStr; 1010 SfxItemSet* pSet = rMedium.GetItemSet(); 1011 const SfxPoolItem* pItem; 1012 if ( pSet && SFX_ITEM_SET == 1013 pSet->GetItemState( SID_FILE_FILTEROPTIONS, sal_True, &pItem ) ) 1014 { 1015 sItStr = ((const SfxStringItem*)pItem)->GetValue(); 1016 } 1017 1018 if (sItStr.Len() == 0) 1019 { 1020 // default for lotus import (from API without options): 1021 // IBM_437 encoding 1022 sItStr = ScGlobal::GetCharsetString( RTL_TEXTENCODING_IBM_437 ); 1023 } 1024 1025 ScColumn::bDoubleAlloc = sal_True; 1026 FltError eError = ScFormatFilter::Get().ScImportLotus123( rMedium, &aDocument, 1027 ScGlobal::GetCharsetValue(sItStr)); 1028 ScColumn::bDoubleAlloc = sal_False; 1029 if (eError != eERR_OK) 1030 { 1031 if (!GetError()) 1032 SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) )); 1033 1034 if( ( eError & ERRCODE_WARNING_MASK ) == ERRCODE_WARNING_MASK ) 1035 bRet = sal_True; 1036 } 1037 else 1038 bRet = sal_True; 1039 bSetColWidths = sal_True; 1040 bSetRowHeights = sal_True; 1041 } 1042 else if ( aFltName.EqualsAscii(pFilterExcel4) || aFltName.EqualsAscii(pFilterExcel5) || 1043 aFltName.EqualsAscii(pFilterExcel95) || aFltName.EqualsAscii(pFilterExcel97) || 1044 aFltName.EqualsAscii(pFilterEx4Temp) || aFltName.EqualsAscii(pFilterEx5Temp) || 1045 aFltName.EqualsAscii(pFilterEx95Temp) || aFltName.EqualsAscii(pFilterEx97Temp) ) 1046 { 1047 EXCIMPFORMAT eFormat = EIF_AUTO; 1048 if ( aFltName.EqualsAscii(pFilterExcel4) || aFltName.EqualsAscii(pFilterEx4Temp) ) 1049 eFormat = EIF_BIFF_LE4; 1050 else if ( aFltName.EqualsAscii(pFilterExcel5) || aFltName.EqualsAscii(pFilterExcel95) || 1051 aFltName.EqualsAscii(pFilterEx5Temp) || aFltName.EqualsAscii(pFilterEx95Temp) ) 1052 eFormat = EIF_BIFF5; 1053 else if ( aFltName.EqualsAscii(pFilterExcel97) || aFltName.EqualsAscii(pFilterEx97Temp) ) 1054 eFormat = EIF_BIFF8; 1055 1056 MakeDrawLayer(); //! im Filter 1057 CalcOutputFactor(); // #93255# prepare update of row height 1058 ScColumn::bDoubleAlloc = sal_True; 1059 FltError eError = ScFormatFilter::Get().ScImportExcel( rMedium, &aDocument, eFormat ); 1060 ScColumn::bDoubleAlloc = sal_False; 1061 aDocument.UpdateFontCharSet(); 1062 if ( aDocument.IsChartListenerCollectionNeedsUpdate() ) 1063 aDocument.UpdateChartListenerCollection(); //! fuer alle Importe? 1064 1065 // #75299# all graphics objects must have names 1066 aDocument.EnsureGraphicNames(); 1067 1068 if (eError == SCWARN_IMPORT_RANGE_OVERFLOW) 1069 { 1070 if (!GetError()) 1071 SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) )); 1072 bRet = sal_True; 1073 } 1074 else if (eError != eERR_OK) 1075 { 1076 if (!GetError()) 1077 SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) )); 1078 } 1079 else 1080 bRet = sal_True; 1081 1082 // #93255# update of row height done inside of Excel filter to speed up chart import 1083 // bSetRowHeights = sal_True; // #75357# optimal row heights must be updated 1084 } 1085 else if (aFltName.EqualsAscii(pFilterAscii)) 1086 { 1087 SfxItemSet* pSet = rMedium.GetItemSet(); 1088 const SfxPoolItem* pItem; 1089 ScAsciiOptions aOptions; 1090 sal_Bool bOptInit = sal_False; 1091 1092 if ( pSet && SFX_ITEM_SET == 1093 pSet->GetItemState( SID_FILE_FILTEROPTIONS, sal_True, &pItem ) ) 1094 { 1095 aOptions.ReadFromString( ((const SfxStringItem*)pItem)->GetValue() ); 1096 bOptInit = sal_True; 1097 } 1098 1099 if ( !bOptInit ) 1100 { 1101 // default for ascii import (from API without options): 1102 // ISO8859-1/MS_1252 encoding, comma, double quotes 1103 1104 aOptions.SetCharSet( RTL_TEXTENCODING_MS_1252 ); 1105 aOptions.SetFieldSeps( (sal_Unicode) ',' ); 1106 aOptions.SetTextSep( (sal_Unicode) '"' ); 1107 } 1108 1109 FltError eError = eERR_OK; 1110 sal_Bool bOverflow = sal_False; 1111 1112 if( ! rMedium.IsStorage() ) 1113 { 1114 ScImportExport aImpEx( &aDocument ); 1115 aImpEx.SetExtOptions( aOptions ); 1116 1117 SvStream* pInStream = rMedium.GetInStream(); 1118 if (pInStream) 1119 { 1120 pInStream->SetStreamCharSet( aOptions.GetCharSet() ); 1121 pInStream->Seek( 0 ); 1122 bRet = aImpEx.ImportStream( *pInStream, rMedium.GetBaseURL() ); 1123 eError = bRet ? eERR_OK : SCERR_IMPORT_CONNECT; 1124 aDocument.StartAllListeners(); 1125 aDocument.SetDirty(); 1126 bOverflow = aImpEx.IsOverflow(); 1127 } 1128 else 1129 { 1130 DBG_ERROR( "No Stream" ); 1131 } 1132 } 1133 1134 if (eError != eERR_OK) 1135 { 1136 if (!GetError()) 1137 SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) )); 1138 } 1139 else if ( bOverflow ) 1140 { 1141 if (!GetError()) 1142 SetError(SCWARN_IMPORT_RANGE_OVERFLOW, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) )); 1143 } 1144 bSetColWidths = sal_True; 1145 bSetSimpleTextColWidths = sal_True; 1146 } 1147 else if (aFltName.EqualsAscii(pFilterDBase)) 1148 { 1149 String sItStr; 1150 SfxItemSet* pSet = rMedium.GetItemSet(); 1151 const SfxPoolItem* pItem; 1152 if ( pSet && SFX_ITEM_SET == 1153 pSet->GetItemState( SID_FILE_FILTEROPTIONS, sal_True, &pItem ) ) 1154 { 1155 sItStr = ((const SfxStringItem*)pItem)->GetValue(); 1156 } 1157 1158 if (sItStr.Len() == 0) 1159 { 1160 // default for dBase import (from API without options): 1161 // IBM_850 encoding 1162 1163 sItStr = ScGlobal::GetCharsetString( RTL_TEXTENCODING_IBM_850 ); 1164 } 1165 1166 sal_uLong eError = DBaseImport( rMedium.GetPhysicalName(), 1167 ScGlobal::GetCharsetValue(sItStr), bSimpleColWidth ); 1168 1169 if (eError != eERR_OK) 1170 { 1171 if (!GetError()) 1172 SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) )); 1173 bRet = ( eError == SCWARN_IMPORT_RANGE_OVERFLOW ); 1174 } 1175 else 1176 bRet = sal_True; 1177 1178 aColWidthRange.aStart.SetRow( 1 ); // Spaltenheader nicht 1179 bSetColWidths = sal_True; 1180 bSetSimpleTextColWidths = sal_True; 1181 // Memo-Felder fuehren zu einem bSimpleColWidth[nCol]==FALSE 1182 for ( SCCOL nCol=0; nCol <= MAXCOL && !bSetRowHeights; nCol++ ) 1183 { 1184 if ( !bSimpleColWidth[nCol] ) 1185 bSetRowHeights = sal_True; 1186 } 1187 } 1188 else if (aFltName.EqualsAscii(pFilterDif)) 1189 { 1190 SvStream* pStream = rMedium.GetInStream(); 1191 if (pStream) 1192 { 1193 FltError eError; 1194 String sItStr; 1195 SfxItemSet* pSet = rMedium.GetItemSet(); 1196 const SfxPoolItem* pItem; 1197 if ( pSet && SFX_ITEM_SET == 1198 pSet->GetItemState( SID_FILE_FILTEROPTIONS, sal_True, &pItem ) ) 1199 { 1200 sItStr = ((const SfxStringItem*)pItem)->GetValue(); 1201 } 1202 1203 if (sItStr.Len() == 0) 1204 { 1205 // default for DIF import (from API without options): 1206 // ISO8859-1/MS_1252 encoding 1207 1208 sItStr = ScGlobal::GetCharsetString( RTL_TEXTENCODING_MS_1252 ); 1209 } 1210 1211 eError = ScFormatFilter::Get().ScImportDif( *pStream, &aDocument, ScAddress(0,0,0), 1212 ScGlobal::GetCharsetValue(sItStr)); 1213 if (eError != eERR_OK) 1214 { 1215 if (!GetError()) 1216 SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) )); 1217 1218 if( ( eError & ERRCODE_WARNING_MASK ) == ERRCODE_WARNING_MASK ) 1219 bRet = sal_True; 1220 } 1221 else 1222 bRet = sal_True; 1223 } 1224 bSetColWidths = sal_True; 1225 bSetSimpleTextColWidths = sal_True; 1226 bSetRowHeights = sal_True; 1227 } 1228 else if (aFltName.EqualsAscii(pFilterSylk)) 1229 { 1230 FltError eError = SCERR_IMPORT_UNKNOWN; 1231 if( !rMedium.IsStorage() ) 1232 { 1233 ScImportExport aImpEx( &aDocument ); 1234 1235 SvStream* pInStream = rMedium.GetInStream(); 1236 if (pInStream) 1237 { 1238 pInStream->Seek( 0 ); 1239 bRet = aImpEx.ImportStream( *pInStream, rMedium.GetBaseURL(), SOT_FORMATSTR_ID_SYLK ); 1240 eError = bRet ? eERR_OK : SCERR_IMPORT_UNKNOWN; 1241 aDocument.StartAllListeners(); 1242 aDocument.SetDirty(); 1243 } 1244 else 1245 { 1246 DBG_ERROR( "No Stream" ); 1247 } 1248 } 1249 1250 if ( eError != eERR_OK && !GetError() ) 1251 SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) )); 1252 bSetColWidths = sal_True; 1253 bSetSimpleTextColWidths = sal_True; 1254 bSetRowHeights = sal_True; 1255 } 1256 else if (aFltName.EqualsAscii(pFilterQPro6)) 1257 { 1258 ScColumn::bDoubleAlloc = sal_True; 1259 FltError eError = ScFormatFilter::Get().ScImportQuattroPro( rMedium, &aDocument); 1260 ScColumn::bDoubleAlloc = sal_False; 1261 if (eError != eERR_OK) 1262 { 1263 if (!GetError()) 1264 SetError( eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); 1265 if( ( eError & ERRCODE_WARNING_MASK ) == ERRCODE_WARNING_MASK ) 1266 bRet = sal_True; 1267 } 1268 else 1269 bRet = sal_True; 1270 // TODO: Filter should set column widths. Not doing it here, it may 1271 // result in very narrow or wide columns, depending on content. 1272 // Setting row heights makes cells with font size attribution or 1273 // wrapping enabled look nicer.. 1274 bSetRowHeights = sal_True; 1275 } 1276 else if (aFltName.EqualsAscii(pFilterRtf)) 1277 { 1278 FltError eError = SCERR_IMPORT_UNKNOWN; 1279 if( !rMedium.IsStorage() ) 1280 { 1281 SvStream* pInStream = rMedium.GetInStream(); 1282 if (pInStream) 1283 { 1284 pInStream->Seek( 0 ); 1285 ScRange aRange; 1286 eError = ScFormatFilter::Get().ScImportRTF( *pInStream, rMedium.GetBaseURL(), &aDocument, aRange ); 1287 if (eError != eERR_OK) 1288 { 1289 if (!GetError()) 1290 SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) )); 1291 1292 if( ( eError & ERRCODE_WARNING_MASK ) == ERRCODE_WARNING_MASK ) 1293 bRet = sal_True; 1294 } 1295 else 1296 bRet = sal_True; 1297 aDocument.StartAllListeners(); 1298 aDocument.SetDirty(); 1299 bSetColWidths = sal_True; 1300 bSetRowHeights = sal_True; 1301 } 1302 else 1303 { 1304 DBG_ERROR( "No Stream" ); 1305 } 1306 } 1307 1308 if ( eError != eERR_OK && !GetError() ) 1309 SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) )); 1310 } 1311 else if (aFltName.EqualsAscii(pFilterHtml) || aFltName.EqualsAscii(pFilterHtmlWebQ)) 1312 { 1313 FltError eError = SCERR_IMPORT_UNKNOWN; 1314 sal_Bool bWebQuery = aFltName.EqualsAscii(pFilterHtmlWebQ); 1315 if( !rMedium.IsStorage() ) 1316 { 1317 SvStream* pInStream = rMedium.GetInStream(); 1318 if (pInStream) 1319 { 1320 LanguageType eLang = LANGUAGE_SYSTEM; 1321 bool bDateConvert = false; 1322 SfxItemSet* pSet = rMedium.GetItemSet(); 1323 const SfxPoolItem* pItem; 1324 if ( pSet && SFX_ITEM_SET == 1325 pSet->GetItemState( SID_FILE_FILTEROPTIONS, sal_True, &pItem ) ) 1326 { 1327 String aFilterOption = (static_cast<const SfxStringItem*>(pItem))->GetValue(); 1328 lcl_parseHtmlFilterOption(aFilterOption, eLang, bDateConvert); 1329 } 1330 1331 pInStream->Seek( 0 ); 1332 ScRange aRange; 1333 // HTML macht eigenes ColWidth/RowHeight 1334 CalcOutputFactor(); 1335 SvNumberFormatter aNumFormatter(aDocument.GetServiceManager(), eLang); 1336 eError = ScFormatFilter::Get().ScImportHTML( *pInStream, rMedium.GetBaseURL(), &aDocument, aRange, 1337 GetOutputFactor(), !bWebQuery, &aNumFormatter, bDateConvert ); 1338 if (eError != eERR_OK) 1339 { 1340 if (!GetError()) 1341 SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) )); 1342 1343 if( ( eError & ERRCODE_WARNING_MASK ) == ERRCODE_WARNING_MASK ) 1344 bRet = sal_True; 1345 } 1346 else 1347 bRet = sal_True; 1348 aDocument.StartAllListeners(); 1349 aDocument.SetDirty(); 1350 } 1351 else 1352 { 1353 DBG_ERROR( "No Stream" ); 1354 } 1355 } 1356 1357 if ( eError != eERR_OK && !GetError() ) 1358 SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) )); 1359 } 1360 else 1361 { 1362 if (!GetError()) 1363 SetError(SCERR_IMPORT_NI, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) )); 1364 } 1365 1366 if (!bCalc3) 1367 aDocument.SetInsertingFromOtherDoc( sal_False ); 1368 } 1369 else 1370 { 1371 DBG_ERROR("Kein Filter bei ConvertFrom"); 1372 } 1373 1374 InitItems(); 1375 CalcOutputFactor(); 1376 if ( bRet && (bSetColWidths || bSetRowHeights) ) 1377 { // Spaltenbreiten/Zeilenhoehen anpassen, Basis 100% Zoom 1378 Fraction aZoom( 1, 1 ); 1379 double nPPTX = ScGlobal::nScreenPPTX * (double) aZoom 1380 / GetOutputFactor(); // Faktor ist Drucker zu Bildschirm 1381 double nPPTY = ScGlobal::nScreenPPTY * (double) aZoom; 1382 VirtualDevice aVirtDev; 1383 // all sheets (for Excel import) 1384 SCTAB nTabCount = aDocument.GetTableCount(); 1385 for (SCTAB nTab=0; nTab<nTabCount; nTab++) 1386 { 1387 SCCOL nEndCol; 1388 SCROW nEndRow; 1389 aDocument.GetCellArea( nTab, nEndCol, nEndRow ); 1390 aColWidthRange.aEnd.SetCol( nEndCol ); 1391 aColWidthRange.aEnd.SetRow( nEndRow ); 1392 ScMarkData aMark; 1393 aMark.SetMarkArea( aColWidthRange ); 1394 aMark.MarkToMulti(); 1395 // Reihenfolge erst Breite dann Hoehe ist wichtig (vergl. hund.rtf) 1396 if ( bSetColWidths ) 1397 { 1398 for ( SCCOL nCol=0; nCol <= nEndCol; nCol++ ) 1399 { 1400 sal_uInt16 nWidth = aDocument.GetOptimalColWidth( 1401 nCol, nTab, &aVirtDev, nPPTX, nPPTY, aZoom, aZoom, sal_False, &aMark, 1402 (bSetSimpleTextColWidths && bSimpleColWidth[nCol]) ); 1403 aDocument.SetColWidth( nCol, nTab, 1404 nWidth + (sal_uInt16)ScGlobal::nLastColWidthExtra ); 1405 } 1406 } 1407 // if ( bSetRowHeights ) 1408 // { 1409 // // nExtra must be 0 1410 // aDocument.SetOptimalHeight( 0, nEndRow, nTab, 0, &aVirtDev, 1411 // nPPTX, nPPTY, aZoom, aZoom, sal_False ); 1412 // } 1413 } 1414 if ( bSetRowHeights ) 1415 UpdateAllRowHeights(); // with vdev or printer, depending on configuration 1416 } 1417 FinishedLoading( SFX_LOADED_MAINDOCUMENT | SFX_LOADED_IMAGES ); 1418 1419 // #73762# invalidate eventually temporary table areas 1420 if ( bRet ) 1421 aDocument.InvalidateTableArea(); 1422 1423 bIsEmpty = sal_False; 1424 1425 return bRet; 1426 } 1427 1428 1429 ScDocShell::PrepareSaveGuard::PrepareSaveGuard( ScDocShell& rDocShell ) 1430 : mrDocShell( rDocShell) 1431 { 1432 // DoEnterHandler not here (because of AutoSave), is in ExecuteSave. 1433 1434 ScChartListenerCollection* pCharts = mrDocShell.aDocument.GetChartListenerCollection(); 1435 if (pCharts) 1436 pCharts->UpdateDirtyCharts(); // Charts to be updated. 1437 mrDocShell.aDocument.StopTemporaryChartLock(); 1438 if (mrDocShell.pAutoStyleList) 1439 mrDocShell.pAutoStyleList->ExecuteAllNow(); // Execute template timeouts now. 1440 if (mrDocShell.aDocument.HasExternalRefManager()) 1441 { 1442 ScExternalRefManager* pRefMgr = mrDocShell.aDocument.GetExternalRefManager(); 1443 if (pRefMgr && pRefMgr->hasExternalData()) 1444 { 1445 pRefMgr->setAllCacheTableReferencedStati( false); 1446 mrDocShell.aDocument.MarkUsedExternalReferences(); // Mark tables of external references to be written. 1447 } 1448 } 1449 if (mrDocShell.GetCreateMode()== SFX_CREATE_MODE_STANDARD) 1450 mrDocShell.SfxObjectShell::SetVisArea( Rectangle() ); // "Normally" worked on => no VisArea. 1451 } 1452 1453 ScDocShell::PrepareSaveGuard::~PrepareSaveGuard() 1454 { 1455 if (mrDocShell.aDocument.HasExternalRefManager()) 1456 { 1457 ScExternalRefManager* pRefMgr = mrDocShell.aDocument.GetExternalRefManager(); 1458 if (pRefMgr && pRefMgr->hasExternalData()) 1459 { 1460 // Prevent accidental data loss due to lack of knowledge. 1461 pRefMgr->setAllCacheTableReferencedStati( true); 1462 } 1463 } 1464 } 1465 1466 1467 sal_Bool __EXPORT ScDocShell::Save() 1468 { 1469 RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::Save" ); 1470 1471 ScRefreshTimerProtector( aDocument.GetRefreshTimerControlAddress() ); 1472 1473 PrepareSaveGuard aPrepareGuard( *this); 1474 1475 // wait cursor is handled with progress bar 1476 sal_Bool bRet = SfxObjectShell::Save(); 1477 if( bRet ) 1478 bRet = SaveXML( GetMedium(), NULL ); 1479 return bRet; 1480 } 1481 1482 1483 sal_Bool __EXPORT ScDocShell::SaveAs( SfxMedium& rMedium ) 1484 { 1485 RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::SaveAs" ); 1486 1487 #if ENABLE_SHEET_PROTECTION 1488 ScTabViewShell* pViewShell = GetBestViewShell(); 1489 if (pViewShell && ScPassHashHelper::needsPassHashRegen(aDocument, PASSHASH_OOO)) 1490 { 1491 if (!pViewShell->ExecuteRetypePassDlg(PASSHASH_OOO)) 1492 // password re-type cancelled. Don't save the document. 1493 return false; 1494 } 1495 #endif 1496 1497 ScRefreshTimerProtector( aDocument.GetRefreshTimerControlAddress() ); 1498 1499 PrepareSaveGuard aPrepareGuard( *this); 1500 1501 // wait cursor is handled with progress bar 1502 sal_Bool bRet = SfxObjectShell::SaveAs( rMedium ); 1503 if( bRet ) 1504 bRet = SaveXML( &rMedium, NULL ); 1505 1506 return bRet; 1507 } 1508 1509 1510 sal_Bool __EXPORT ScDocShell::IsInformationLost() 1511 { 1512 /* 1513 const SfxFilter *pFilt = GetMedium()->GetFilter(); 1514 sal_Bool bRet = pFilt && pFilt->IsAlienFormat() && bNoInformLost; 1515 if (bNoInformLost) // nur einmal!! 1516 bNoInformLost = sal_False; 1517 return bRet; 1518 */ 1519 //!!! bei Gelegenheit ein korrekte eigene Behandlung einbauen 1520 1521 return SfxObjectShell::IsInformationLost(); 1522 } 1523 1524 1525 // Xcl-like column width measured in characters of standard font. 1526 xub_StrLen lcl_ScDocShell_GetColWidthInChars( sal_uInt16 nWidth ) 1527 { 1528 // double fColScale = 1.0; 1529 double f = nWidth; 1530 f *= 1328.0 / 25.0; 1531 f += 90.0; 1532 f *= 1.0 / 23.0; 1533 // f /= fColScale * 256.0; 1534 f /= 256.0; 1535 1536 return xub_StrLen( f ); 1537 } 1538 1539 1540 void lcl_ScDocShell_GetFixedWidthString( String& rStr, const ScDocument& rDoc, 1541 SCTAB nTab, SCCOL nCol, sal_Bool bValue, SvxCellHorJustify eHorJust ) 1542 { 1543 xub_StrLen nLen = lcl_ScDocShell_GetColWidthInChars( 1544 rDoc.GetColWidth( nCol, nTab ) ); 1545 if ( nLen < rStr.Len() ) 1546 { 1547 if ( bValue ) 1548 rStr.AssignAscii( "###" ); 1549 rStr.Erase( nLen ); 1550 } 1551 if ( nLen > rStr.Len() ) 1552 { 1553 if ( bValue && eHorJust == SVX_HOR_JUSTIFY_STANDARD ) 1554 eHorJust = SVX_HOR_JUSTIFY_RIGHT; 1555 switch ( eHorJust ) 1556 { 1557 case SVX_HOR_JUSTIFY_RIGHT: 1558 { 1559 String aTmp; 1560 aTmp.Fill( nLen - rStr.Len() ); 1561 rStr.Insert( aTmp, 0 ); 1562 } 1563 break; 1564 case SVX_HOR_JUSTIFY_CENTER: 1565 { 1566 xub_StrLen nLen2 = (nLen - rStr.Len()) / 2; 1567 String aTmp; 1568 aTmp.Fill( nLen2 ); 1569 rStr.Insert( aTmp, 0 ); 1570 rStr.Expand( nLen ); 1571 } 1572 break; 1573 default: 1574 rStr.Expand( nLen ); 1575 } 1576 } 1577 } 1578 1579 1580 void lcl_ScDocShell_WriteEmptyFixedWidthString( SvStream& rStream, 1581 const ScDocument& rDoc, SCTAB nTab, SCCOL nCol ) 1582 { 1583 String aString; 1584 lcl_ScDocShell_GetFixedWidthString( aString, rDoc, nTab, nCol, sal_False, 1585 SVX_HOR_JUSTIFY_STANDARD ); 1586 rStream.WriteUnicodeOrByteText( aString ); 1587 } 1588 1589 1590 void ScDocShell::AsciiSave( SvStream& rStream, const ScImportOptions& rAsciiOpt ) 1591 { 1592 sal_Unicode cDelim = rAsciiOpt.nFieldSepCode; 1593 sal_Unicode cStrDelim = rAsciiOpt.nTextSepCode; 1594 CharSet eCharSet = rAsciiOpt.eCharSet; 1595 sal_Bool bFixedWidth = rAsciiOpt.bFixedWidth; 1596 sal_Bool bSaveAsShown = rAsciiOpt.bSaveAsShown; 1597 1598 CharSet eOldCharSet = rStream.GetStreamCharSet(); 1599 rStream.SetStreamCharSet( eCharSet ); 1600 sal_uInt16 nOldNumberFormatInt = rStream.GetNumberFormatInt(); 1601 ByteString aStrDelimEncoded; // only used if not Unicode 1602 UniString aStrDelimDecoded; // only used if context encoding 1603 ByteString aDelimEncoded; 1604 UniString aDelimDecoded; 1605 sal_Bool bContextOrNotAsciiEncoding; 1606 if ( eCharSet == RTL_TEXTENCODING_UNICODE ) 1607 { 1608 rStream.StartWritingUnicodeText(); 1609 bContextOrNotAsciiEncoding = sal_False; 1610 } 1611 else 1612 { 1613 aStrDelimEncoded = ByteString( cStrDelim, eCharSet ); 1614 aDelimEncoded = ByteString( cDelim, eCharSet ); 1615 rtl_TextEncodingInfo aInfo; 1616 aInfo.StructSize = sizeof(aInfo); 1617 if ( rtl_getTextEncodingInfo( eCharSet, &aInfo ) ) 1618 { 1619 bContextOrNotAsciiEncoding = 1620 (((aInfo.Flags & RTL_TEXTENCODING_INFO_CONTEXT) != 0) || 1621 ((aInfo.Flags & RTL_TEXTENCODING_INFO_ASCII) == 0)); 1622 if ( bContextOrNotAsciiEncoding ) 1623 { 1624 aStrDelimDecoded = String( aStrDelimEncoded, eCharSet ); 1625 aDelimDecoded = String( aDelimEncoded, eCharSet ); 1626 } 1627 } 1628 else 1629 bContextOrNotAsciiEncoding = sal_False; 1630 } 1631 1632 SCCOL nStartCol = 0; 1633 SCROW nStartRow = 0; 1634 SCTAB nTab = GetSaveTab(); 1635 SCCOL nEndCol; 1636 SCROW nEndRow; 1637 aDocument.GetCellArea( nTab, nEndCol, nEndRow ); 1638 1639 ScProgress aProgress( this, ScGlobal::GetRscString( STR_SAVE_DOC ), nEndRow ); 1640 1641 String aString; 1642 1643 ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell, SfxViewShell::Current()); 1644 const ScViewOptions& rOpt = (pViewSh) 1645 ? pViewSh->GetViewData()->GetOptions() 1646 : aDocument.GetViewOptions(); 1647 sal_Bool bShowFormulas = rOpt.GetOption( VOPT_FORMULAS ); 1648 sal_Bool bTabProtect = aDocument.IsTabProtected( nTab ); 1649 1650 SCCOL nCol; 1651 SCROW nRow; 1652 SCCOL nNextCol = nStartCol; 1653 SCROW nNextRow = nStartRow; 1654 SCCOL nEmptyCol; 1655 SCROW nEmptyRow; 1656 SvNumberFormatter& rFormatter = *aDocument.GetFormatTable(); 1657 1658 ScHorizontalCellIterator aIter( &aDocument, nTab, nStartCol, nStartRow, 1659 nEndCol, nEndRow ); 1660 ScBaseCell* pCell; 1661 while ( ( pCell = aIter.GetNext( nCol, nRow ) ) != NULL ) 1662 { 1663 sal_Bool bProgress = sal_False; // only upon line change 1664 if ( nNextRow < nRow ) 1665 { // empty rows or/and empty columns up to end of row 1666 bProgress = sal_True; 1667 for ( nEmptyCol = nNextCol; nEmptyCol < nEndCol; nEmptyCol++ ) 1668 { // remaining columns of last row 1669 if ( bFixedWidth ) 1670 lcl_ScDocShell_WriteEmptyFixedWidthString( rStream, 1671 aDocument, nTab, nEmptyCol ); 1672 else if ( cDelim != 0 ) 1673 rStream.WriteUniOrByteChar( cDelim ); 1674 } 1675 endlub( rStream ); 1676 nNextRow++; 1677 for ( nEmptyRow = nNextRow; nEmptyRow < nRow; nEmptyRow++ ) 1678 { // completely empty rows 1679 for ( nEmptyCol = nStartCol; nEmptyCol < nEndCol; nEmptyCol++ ) 1680 { 1681 if ( bFixedWidth ) 1682 lcl_ScDocShell_WriteEmptyFixedWidthString( rStream, 1683 aDocument, nTab, nEmptyCol ); 1684 else if ( cDelim != 0 ) 1685 rStream.WriteUniOrByteChar( cDelim ); 1686 } 1687 endlub( rStream ); 1688 } 1689 for ( nEmptyCol = nStartCol; nEmptyCol < nCol; nEmptyCol++ ) 1690 { // empty columns at beginning of row 1691 if ( bFixedWidth ) 1692 lcl_ScDocShell_WriteEmptyFixedWidthString( rStream, 1693 aDocument, nTab, nEmptyCol ); 1694 else if ( cDelim != 0 ) 1695 rStream.WriteUniOrByteChar( cDelim ); 1696 } 1697 nNextRow = nRow; 1698 } 1699 else if ( nNextCol < nCol ) 1700 { // empty columns in same row 1701 for ( nEmptyCol = nNextCol; nEmptyCol < nCol; nEmptyCol++ ) 1702 { // columns in between 1703 if ( bFixedWidth ) 1704 lcl_ScDocShell_WriteEmptyFixedWidthString( rStream, 1705 aDocument, nTab, nEmptyCol ); 1706 else if ( cDelim != 0 ) 1707 rStream.WriteUniOrByteChar( cDelim ); 1708 } 1709 } 1710 if ( nCol == nEndCol ) 1711 { 1712 bProgress = sal_True; 1713 nNextCol = nStartCol; 1714 nNextRow = nRow + 1; 1715 } 1716 else 1717 nNextCol = nCol + 1; 1718 1719 CellType eType = pCell->GetCellType(); 1720 if ( bTabProtect ) 1721 { 1722 const ScProtectionAttr* pProtAttr = 1723 (const ScProtectionAttr*) aDocument.GetAttr( 1724 nCol, nRow, nTab, ATTR_PROTECTION ); 1725 if ( pProtAttr->GetHideCell() || 1726 ( eType == CELLTYPE_FORMULA && bShowFormulas && 1727 pProtAttr->GetHideFormula() ) ) 1728 eType = CELLTYPE_NONE; // hide 1729 } 1730 sal_Bool bString; 1731 switch ( eType ) 1732 { 1733 case CELLTYPE_NOTE: 1734 case CELLTYPE_NONE: 1735 aString.Erase(); 1736 bString = sal_False; 1737 break; 1738 case CELLTYPE_FORMULA : 1739 { 1740 sal_uInt16 nErrCode; 1741 if ( bShowFormulas ) 1742 { 1743 ((ScFormulaCell*)pCell)->GetFormula( aString ); 1744 bString = sal_True; 1745 } 1746 else if ( ( nErrCode = ((ScFormulaCell*)pCell)->GetErrCode() ) != 0 ) 1747 { 1748 aString = ScGlobal::GetErrorString( nErrCode ); 1749 bString = sal_True; 1750 } 1751 else if ( ((ScFormulaCell*)pCell)->IsValue() ) 1752 { 1753 sal_uInt32 nFormat; 1754 aDocument.GetNumberFormat( nCol, nRow, nTab, nFormat ); 1755 if ( bFixedWidth || bSaveAsShown ) 1756 { 1757 Color* pDummy; 1758 ScCellFormat::GetString( pCell, nFormat, aString, &pDummy, rFormatter ); 1759 bString = bSaveAsShown && rFormatter.IsTextFormat( nFormat); 1760 } 1761 else 1762 { 1763 ScCellFormat::GetInputString( pCell, nFormat, aString, rFormatter ); 1764 bString = sal_False; 1765 } 1766 } 1767 else 1768 { 1769 if ( bSaveAsShown ) 1770 { 1771 sal_uInt32 nFormat; 1772 aDocument.GetNumberFormat( nCol, nRow, nTab, nFormat ); 1773 Color* pDummy; 1774 ScCellFormat::GetString( pCell, nFormat, aString, &pDummy, rFormatter ); 1775 } 1776 else 1777 ((ScFormulaCell*)pCell)->GetString( aString ); 1778 bString = sal_True; 1779 } 1780 } 1781 break; 1782 case CELLTYPE_STRING : 1783 if ( bSaveAsShown ) 1784 { 1785 sal_uInt32 nFormat; 1786 aDocument.GetNumberFormat( nCol, nRow, nTab, nFormat ); 1787 Color* pDummy; 1788 ScCellFormat::GetString( pCell, nFormat, aString, &pDummy, rFormatter ); 1789 } 1790 else 1791 ((ScStringCell*)pCell)->GetString( aString ); 1792 bString = sal_True; 1793 break; 1794 case CELLTYPE_EDIT : 1795 { 1796 const EditTextObject* pObj; 1797 static_cast<const ScEditCell*>(pCell)->GetData( pObj); 1798 EditEngine& rEngine = aDocument.GetEditEngine(); 1799 rEngine.SetText( *pObj); 1800 aString = rEngine.GetText(); // including LF 1801 bString = sal_True; 1802 } 1803 break; 1804 case CELLTYPE_VALUE : 1805 { 1806 sal_uInt32 nFormat; 1807 aDocument.GetNumberFormat( nCol, nRow, nTab, nFormat ); 1808 if ( bFixedWidth || bSaveAsShown ) 1809 { 1810 Color* pDummy; 1811 ScCellFormat::GetString( pCell, nFormat, aString, &pDummy, rFormatter ); 1812 bString = bSaveAsShown && rFormatter.IsTextFormat( nFormat); 1813 } 1814 else 1815 { 1816 ScCellFormat::GetInputString( pCell, nFormat, aString, rFormatter ); 1817 bString = sal_False; 1818 } 1819 } 1820 break; 1821 default: 1822 DBG_ERROR( "ScDocShell::AsciiSave: unknown CellType" ); 1823 aString.Erase(); 1824 bString = sal_False; 1825 } 1826 1827 if ( bFixedWidth ) 1828 { 1829 SvxCellHorJustify eHorJust = (SvxCellHorJustify) 1830 ((const SvxHorJustifyItem*) aDocument.GetAttr( nCol, nRow, 1831 nTab, ATTR_HOR_JUSTIFY ))->GetValue(); 1832 lcl_ScDocShell_GetFixedWidthString( aString, aDocument, nTab, nCol, 1833 !bString, eHorJust ); 1834 rStream.WriteUnicodeOrByteText( aString ); 1835 } 1836 else 1837 { 1838 if (!bString && cStrDelim != 0 && aString.Len() > 0) 1839 { 1840 sal_Unicode c = aString.GetChar(0); 1841 bString = (c == cStrDelim || c == ' ' || 1842 aString.GetChar( aString.Len()-1) == ' ' || 1843 aString.Search( cStrDelim) != STRING_NOTFOUND); 1844 if (!bString && cDelim != 0) 1845 bString = (aString.Search( cDelim) != STRING_NOTFOUND); 1846 } 1847 if ( bString ) 1848 { 1849 if ( cStrDelim != 0 ) //@ BugId 55355 1850 { 1851 if ( eCharSet == RTL_TEXTENCODING_UNICODE ) 1852 { 1853 xub_StrLen nPos = aString.Search( cStrDelim ); 1854 // #i116636# quotes are needed if text delimiter (quote), field delimiter, or LF is in the cell text 1855 bool bNeedQuotes = rAsciiOpt.bQuoteAllText || 1856 ( nPos != STRING_NOTFOUND ) || 1857 ( aString.Search( cDelim ) != STRING_NOTFOUND ) || 1858 ( aString.Search( sal_Unicode(_LF) ) != STRING_NOTFOUND ); 1859 while ( nPos != STRING_NOTFOUND ) 1860 { 1861 aString.Insert( cStrDelim, nPos ); 1862 nPos = aString.Search( cStrDelim, nPos+2 ); 1863 } 1864 if ( bNeedQuotes ) 1865 rStream.WriteUniOrByteChar( cStrDelim, eCharSet ); 1866 rStream.WriteUnicodeText( aString ); 1867 if ( bNeedQuotes ) 1868 rStream.WriteUniOrByteChar( cStrDelim, eCharSet ); 1869 } 1870 else 1871 { 1872 // #105549# This is nasty. The Unicode to byte encoding 1873 // may convert typographical quotation marks to ASCII 1874 // quotation marks, which may interfer with the delimiter, 1875 // so we have to escape delimiters after the string has 1876 // been encoded. Since this may happen also with UTF-8 1877 // encoded typographical quotation marks if such was 1878 // specified as a delimiter we have to check for the full 1879 // encoded delimiter string, not just one character. 1880 // Now for RTL_TEXTENCODING_ISO_2022_... and similar brain 1881 // dead encodings where one code point (and especially a 1882 // low ASCII value) may represent different characters, we 1883 // have to convert forth and back and forth again. Same for 1884 // UTF-7 since it is a context sensitive encoding too. 1885 1886 if ( bContextOrNotAsciiEncoding ) 1887 { 1888 // to byte encoding 1889 ByteString aStrEnc( aString, eCharSet ); 1890 // back to Unicode 1891 UniString aStrDec( aStrEnc, eCharSet ); 1892 // search on re-decoded string 1893 xub_StrLen nPos = aStrDec.Search( aStrDelimDecoded ); 1894 bool bNeedQuotes = rAsciiOpt.bQuoteAllText || 1895 ( nPos != STRING_NOTFOUND ) || 1896 ( aStrDec.Search( aDelimDecoded ) != STRING_NOTFOUND ) || 1897 ( aStrDec.Search( sal_Unicode(_LF) ) != STRING_NOTFOUND ); 1898 while ( nPos != STRING_NOTFOUND ) 1899 { 1900 aStrDec.Insert( aStrDelimDecoded, nPos ); 1901 nPos = aStrDec.Search( aStrDelimDecoded, 1902 nPos+1+aStrDelimDecoded.Len() ); 1903 } 1904 // write byte re-encoded 1905 if ( bNeedQuotes ) 1906 rStream.WriteUniOrByteChar( cStrDelim, eCharSet ); 1907 rStream.WriteUnicodeOrByteText( aStrDec, eCharSet ); 1908 if ( bNeedQuotes ) 1909 rStream.WriteUniOrByteChar( cStrDelim, eCharSet ); 1910 } 1911 else 1912 { 1913 ByteString aStrEnc( aString, eCharSet ); 1914 // search on encoded string 1915 xub_StrLen nPos = aStrEnc.Search( aStrDelimEncoded ); 1916 bool bNeedQuotes = rAsciiOpt.bQuoteAllText || 1917 ( nPos != STRING_NOTFOUND ) || 1918 ( aStrEnc.Search( aDelimEncoded ) != STRING_NOTFOUND ) || 1919 ( aStrEnc.Search( sal_Char(_LF) ) != STRING_NOTFOUND ); 1920 while ( nPos != STRING_NOTFOUND ) 1921 { 1922 aStrEnc.Insert( aStrDelimEncoded, nPos ); 1923 nPos = aStrEnc.Search( aStrDelimEncoded, 1924 nPos+1+aStrDelimEncoded.Len() ); 1925 } 1926 // write byte encoded 1927 if ( bNeedQuotes ) 1928 rStream.Write( aStrDelimEncoded.GetBuffer(), 1929 aStrDelimEncoded.Len() ); 1930 rStream.Write( aStrEnc.GetBuffer(), aStrEnc.Len() ); 1931 if ( bNeedQuotes ) 1932 rStream.Write( aStrDelimEncoded.GetBuffer(), 1933 aStrDelimEncoded.Len() ); 1934 } 1935 } 1936 } 1937 else 1938 rStream.WriteUnicodeOrByteText( aString ); 1939 } 1940 else 1941 rStream.WriteUnicodeOrByteText( aString ); 1942 } 1943 1944 if( nCol < nEndCol ) 1945 { 1946 if(cDelim!=0) //@ BugId 55355 1947 rStream.WriteUniOrByteChar( cDelim ); 1948 } 1949 else 1950 endlub( rStream ); 1951 1952 if ( bProgress ) 1953 aProgress.SetStateOnPercent( nRow ); 1954 } 1955 1956 // write out empty if requested 1957 if ( nNextRow <= nEndRow ) 1958 { 1959 for ( nEmptyCol = nNextCol; nEmptyCol < nEndCol; nEmptyCol++ ) 1960 { // remaining empty columns of last row 1961 if ( bFixedWidth ) 1962 lcl_ScDocShell_WriteEmptyFixedWidthString( rStream, 1963 aDocument, nTab, nEmptyCol ); 1964 else if ( cDelim != 0 ) 1965 rStream.WriteUniOrByteChar( cDelim ); 1966 } 1967 endlub( rStream ); 1968 nNextRow++; 1969 } 1970 for ( nEmptyRow = nNextRow; nEmptyRow <= nEndRow; nEmptyRow++ ) 1971 { // entire empty rows 1972 for ( nEmptyCol = nStartCol; nEmptyCol < nEndCol; nEmptyCol++ ) 1973 { 1974 if ( bFixedWidth ) 1975 lcl_ScDocShell_WriteEmptyFixedWidthString( rStream, 1976 aDocument, nTab, nEmptyCol ); 1977 else if ( cDelim != 0 ) 1978 rStream.WriteUniOrByteChar( cDelim ); 1979 } 1980 endlub( rStream ); 1981 } 1982 1983 rStream.SetStreamCharSet( eOldCharSet ); 1984 rStream.SetNumberFormatInt( nOldNumberFormatInt ); 1985 } 1986 1987 sal_Bool __EXPORT ScDocShell::ConvertTo( SfxMedium &rMed ) 1988 { 1989 RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::ConvertTo" ); 1990 1991 ScRefreshTimerProtector( aDocument.GetRefreshTimerControlAddress() ); 1992 1993 // #i6500# don't call DoEnterHandler here (doesn't work with AutoSave), 1994 // it's already in ExecuteSave (as for Save and SaveAs) 1995 1996 if (pAutoStyleList) 1997 pAutoStyleList->ExecuteAllNow(); // Vorlagen-Timeouts jetzt ausfuehren 1998 if (GetCreateMode()== SFX_CREATE_MODE_STANDARD) 1999 SfxObjectShell::SetVisArea( Rectangle() ); // normal bearbeitet -> keine VisArea 2000 2001 DBG_ASSERT( rMed.GetFilter(), "Filter == 0" ); 2002 2003 sal_Bool bRet = sal_False; 2004 String aFltName = rMed.GetFilter()->GetFilterName(); 2005 2006 /* 2007 if (aFltName.EqualsAscii(pFilterLotus)) 2008 { 2009 SvStream* pStream = rMed.GetOutStream(); 2010 if (pStream) 2011 { 2012 FltError eError = ScFormatFilter::Get().ScExportLotus123( *pStream, &aDocument, ExpWK1, 2013 CHARSET_IBMPC_437 ); 2014 bRet = eError == eERR_OK; 2015 } 2016 } 2017 else 2018 */ 2019 if (aFltName.EqualsAscii(pFilterXML)) 2020 { 2021 //TODO/LATER: this shouldn't happen! 2022 DBG_ERROR("XML filter in ConvertFrom?!"); 2023 bRet = SaveXML( &rMed, NULL ); 2024 } 2025 else if (aFltName.EqualsAscii(pFilterExcel5) || aFltName.EqualsAscii(pFilterExcel95) || 2026 aFltName.EqualsAscii(pFilterExcel97) || aFltName.EqualsAscii(pFilterEx5Temp) || 2027 aFltName.EqualsAscii(pFilterEx95Temp) || aFltName.EqualsAscii(pFilterEx97Temp) || 2028 aFltName.EqualsAscii(pFilterEx07Xml)) 2029 { 2030 WaitObject aWait( GetActiveDialogParent() ); 2031 2032 bool bDoSave = true; 2033 if( ScTabViewShell* pViewShell = GetBestViewShell() ) 2034 { 2035 ScExtDocOptions* pExtDocOpt = aDocument.GetExtDocOptions(); 2036 if( !pExtDocOpt ) 2037 aDocument.SetExtDocOptions( pExtDocOpt = new ScExtDocOptions ); 2038 pViewShell->GetViewData()->WriteExtOptions( *pExtDocOpt ); 2039 2040 /* #115980# #i104990# If the imported document contains a medium 2041 password, determine if we can save it, otherwise ask the users 2042 whether they want to save without it. */ 2043 if( (rMed.GetFilter()->GetFilterFlags() & SFX_FILTER_ENCRYPTION) == 0 ) 2044 { 2045 SfxItemSet* pItemSet = rMed.GetItemSet(); 2046 const SfxPoolItem* pItem = 0; 2047 if( pItemSet && pItemSet->GetItemState( SID_PASSWORD, sal_True, &pItem ) == SFX_ITEM_SET ) 2048 { 2049 bDoSave = ScWarnPassword::WarningOnPassword( rMed ); 2050 // #i42858# remove password from medium (warn only one time) 2051 if( bDoSave ) 2052 pItemSet->ClearItem( SID_PASSWORD ); 2053 } 2054 } 2055 2056 #if ENABLE_SHEET_PROTECTION 2057 if( bDoSave ) 2058 { 2059 bool bNeedRetypePassDlg = ScPassHashHelper::needsPassHashRegen( aDocument, PASSHASH_XL ); 2060 bDoSave = !bNeedRetypePassDlg || pViewShell->ExecuteRetypePassDlg( PASSHASH_XL ); 2061 } 2062 #endif 2063 } 2064 2065 if( bDoSave ) 2066 { 2067 ExportFormatExcel eFormat = ExpBiff5; 2068 if( aFltName.EqualsAscii( pFilterExcel97 ) || aFltName.EqualsAscii( pFilterEx97Temp ) ) 2069 eFormat = ExpBiff8; 2070 if( aFltName.EqualsAscii( pFilterEx07Xml ) ) 2071 eFormat = Exp2007Xml; 2072 FltError eError = ScFormatFilter::Get().ScExportExcel5( rMed, &aDocument, eFormat, RTL_TEXTENCODING_MS_1252 ); 2073 2074 if( eError && !GetError() ) 2075 SetError( eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); 2076 2077 // don't return false for warnings 2078 bRet = ((eError & ERRCODE_WARNING_MASK) == ERRCODE_WARNING_MASK) || (eError == eERR_OK); 2079 } 2080 else 2081 { 2082 // export aborted, i.e. "Save without password" warning 2083 SetError( ERRCODE_ABORT, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); 2084 } 2085 } 2086 else if (aFltName.EqualsAscii(pFilterAscii)) 2087 { 2088 SvStream* pStream = rMed.GetOutStream(); 2089 if (pStream) 2090 { 2091 String sItStr; 2092 SfxItemSet* pSet = rMed.GetItemSet(); 2093 const SfxPoolItem* pItem; 2094 if ( pSet && SFX_ITEM_SET == 2095 pSet->GetItemState( SID_FILE_FILTEROPTIONS, sal_True, &pItem ) ) 2096 { 2097 sItStr = ((const SfxStringItem*)pItem)->GetValue(); 2098 } 2099 2100 if ( sItStr.Len() == 0 ) 2101 { 2102 // default for ascii export (from API without options): 2103 // ISO8859-1/MS_1252 encoding, comma, double quotes 2104 2105 ScImportOptions aDefOptions( ',', '"', RTL_TEXTENCODING_MS_1252 ); 2106 sItStr = aDefOptions.BuildString(); 2107 } 2108 2109 WaitObject aWait( GetActiveDialogParent() ); 2110 ScImportOptions aOptions( sItStr ); 2111 AsciiSave( *pStream, aOptions ); 2112 bRet = sal_True; 2113 2114 if (aDocument.GetTableCount() > 1) 2115 if (!rMed.GetError()) 2116 rMed.SetError(SCWARN_EXPORT_ASCII, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) )); 2117 } 2118 } 2119 else if (aFltName.EqualsAscii(pFilterDBase)) 2120 { 2121 String sCharSet; 2122 SfxItemSet* pSet = rMed.GetItemSet(); 2123 const SfxPoolItem* pItem; 2124 if ( pSet && SFX_ITEM_SET == 2125 pSet->GetItemState( SID_FILE_FILTEROPTIONS, sal_True, &pItem ) ) 2126 { 2127 sCharSet = ((const SfxStringItem*)pItem)->GetValue(); 2128 } 2129 2130 if (sCharSet.Len() == 0) 2131 { 2132 // default for dBase export (from API without options): 2133 // IBM_850 encoding 2134 2135 sCharSet = ScGlobal::GetCharsetString( RTL_TEXTENCODING_IBM_850 ); 2136 } 2137 2138 WaitObject aWait( GetActiveDialogParent() ); 2139 // HACK damit Sba geoffnetes TempFile ueberschreiben kann 2140 rMed.CloseOutStream(); 2141 sal_Bool bHasMemo = sal_False; 2142 2143 sal_uLong eError = DBaseExport( rMed.GetPhysicalName(), 2144 ScGlobal::GetCharsetValue(sCharSet), bHasMemo ); 2145 2146 if ( eError != eERR_OK && (eError & ERRCODE_WARNING_MASK) ) 2147 { 2148 //! if ( !rMed.GetError() ) 2149 //! rMed.SetError( eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); 2150 eError = eERR_OK; 2151 } 2152 //! else if ( aDocument.GetTableCount() > 1 && !rMed.GetError() ) 2153 //! rMed.SetError( SCWARN_EXPORT_ASCII, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); 2154 2155 INetURLObject aTmpFile( rMed.GetPhysicalName(), INET_PROT_FILE ); 2156 if ( bHasMemo ) 2157 aTmpFile.setExtension( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("dbt")) ); 2158 if ( eError != eERR_OK ) 2159 { 2160 if (!GetError()) 2161 SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) )); 2162 if ( bHasMemo && IsDocument( aTmpFile ) ) 2163 KillFile( aTmpFile ); 2164 } 2165 else 2166 { 2167 bRet = sal_True; 2168 if ( bHasMemo ) 2169 { 2170 SfxStringItem* pNameItem = 2171 (SfxStringItem*) rMed.GetItemSet()->GetItem( SID_FILE_NAME ); 2172 INetURLObject aDbtFile( pNameItem->GetValue(), INET_PROT_FILE ); 2173 aDbtFile.setExtension( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("dbt")) ); 2174 if ( IsDocument( aDbtFile ) && !KillFile( aDbtFile ) ) 2175 bRet = sal_False; 2176 if ( bRet && !MoveFile( aTmpFile, aDbtFile ) ) 2177 bRet = sal_False; 2178 if ( !bRet ) 2179 { 2180 KillFile( aTmpFile ); 2181 if ( !GetError() ) 2182 SetError( SCERR_EXPORT_DATA, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); 2183 } 2184 } 2185 } 2186 } 2187 else if (aFltName.EqualsAscii(pFilterDif)) 2188 { 2189 SvStream* pStream = rMed.GetOutStream(); 2190 if (pStream) 2191 { 2192 String sItStr; 2193 SfxItemSet* pSet = rMed.GetItemSet(); 2194 const SfxPoolItem* pItem; 2195 if ( pSet && SFX_ITEM_SET == 2196 pSet->GetItemState( SID_FILE_FILTEROPTIONS, sal_True, &pItem ) ) 2197 { 2198 sItStr = ((const SfxStringItem*)pItem)->GetValue(); 2199 } 2200 2201 if (sItStr.Len() == 0) 2202 { 2203 // default for DIF export (from API without options): 2204 // ISO8859-1/MS_1252 encoding 2205 2206 sItStr = ScGlobal::GetCharsetString( RTL_TEXTENCODING_MS_1252 ); 2207 } 2208 2209 WaitObject aWait( GetActiveDialogParent() ); 2210 ScFormatFilter::Get().ScExportDif( *pStream, &aDocument, ScAddress(0,0,0), 2211 ScGlobal::GetCharsetValue(sItStr) ); 2212 bRet = sal_True; 2213 2214 if (aDocument.GetTableCount() > 1) 2215 if (!rMed.GetError()) 2216 rMed.SetError(SCWARN_EXPORT_ASCII, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) )); 2217 } 2218 } 2219 else if (aFltName.EqualsAscii(pFilterSylk)) 2220 { 2221 SvStream* pStream = rMed.GetOutStream(); 2222 if ( pStream ) 2223 { 2224 WaitObject aWait( GetActiveDialogParent() ); 2225 2226 SCCOL nEndCol; 2227 SCROW nEndRow; 2228 aDocument.GetCellArea( 0, nEndCol, nEndRow ); 2229 ScRange aRange( 0,0,0, nEndCol,nEndRow,0 ); 2230 2231 ScImportExport aImExport( &aDocument, aRange ); 2232 aImExport.SetFormulas( sal_True ); 2233 bRet = aImExport.ExportStream( *pStream, rMed.GetBaseURL( true ), SOT_FORMATSTR_ID_SYLK ); 2234 } 2235 } 2236 else if (aFltName.EqualsAscii(pFilterHtml)) 2237 { 2238 SvStream* pStream = rMed.GetOutStream(); 2239 if ( pStream ) 2240 { 2241 WaitObject aWait( GetActiveDialogParent() ); 2242 ScImportExport aImExport( &aDocument ); 2243 aImExport.SetStreamPath( rMed.GetName() ); 2244 bRet = aImExport.ExportStream( *pStream, rMed.GetBaseURL( true ), SOT_FORMATSTR_ID_HTML ); 2245 if ( bRet && aImExport.GetNonConvertibleChars().Len() ) 2246 SetError( *new StringErrorInfo( 2247 SCWARN_EXPORT_NONCONVERTIBLE_CHARS, 2248 aImExport.GetNonConvertibleChars(), 2249 ERRCODE_BUTTON_OK | ERRCODE_MSG_INFO ), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); 2250 } 2251 } 2252 else 2253 { 2254 if (GetError()) 2255 SetError(SCERR_IMPORT_NI, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); 2256 } 2257 return bRet; 2258 } 2259 2260 2261 sal_Bool __EXPORT ScDocShell::SaveCompleted( const uno::Reference < embed::XStorage >& xStor ) 2262 { 2263 return SfxObjectShell::SaveCompleted( xStor ); 2264 } 2265 2266 2267 sal_Bool __EXPORT ScDocShell::DoSaveCompleted( SfxMedium * pNewStor ) 2268 { 2269 sal_Bool bRet = SfxObjectShell::DoSaveCompleted( pNewStor ); 2270 2271 // SC_HINT_DOC_SAVED fuer Wechsel ReadOnly -> Read/Write 2272 Broadcast( SfxSimpleHint( SC_HINT_DOC_SAVED ) ); 2273 return bRet; 2274 } 2275 2276 2277 sal_Bool ScDocShell::QuerySlotExecutable( sal_uInt16 nSlotId ) 2278 { 2279 // #i112634# ask VBA event handlers whether to save or print the document 2280 2281 using namespace ::com::sun::star::script::vba; 2282 2283 sal_Int32 nVbaEventId = VBAEventId::NO_EVENT; 2284 uno::Sequence< uno::Any > aArgs; 2285 switch( nSlotId ) 2286 { 2287 case SID_SAVEDOC: 2288 case SID_SAVEASDOC: 2289 nVbaEventId = VBAEventId::WORKBOOK_BEFORESAVE; 2290 aArgs.realloc( 1 ); 2291 aArgs[ 0 ] <<= (nSlotId == SID_SAVEASDOC); 2292 break; 2293 case SID_PRINTDOC: 2294 case SID_PRINTDOCDIRECT: 2295 nVbaEventId = VBAEventId::WORKBOOK_BEFOREPRINT; 2296 break; 2297 } 2298 2299 sal_Bool bSlotExecutable = sal_True; 2300 if( nVbaEventId != VBAEventId::NO_EVENT ) try 2301 { 2302 uno::Reference< XVBAEventProcessor > xEventProcessor( aDocument.GetVbaEventProcessor(), uno::UNO_QUERY_THROW ); 2303 xEventProcessor->processVbaEvent( nVbaEventId, aArgs ); 2304 } 2305 catch( util::VetoException& ) 2306 { 2307 bSlotExecutable = sal_False; 2308 } 2309 catch( uno::Exception& ) 2310 { 2311 } 2312 return bSlotExecutable; 2313 } 2314 2315 2316 sal_uInt16 __EXPORT ScDocShell::PrepareClose( sal_Bool bUI, sal_Bool bForBrowsing ) 2317 { 2318 if(SC_MOD()->GetCurRefDlgId()>0) 2319 { 2320 SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this ); 2321 if( pFrame ) 2322 { 2323 SfxViewShell* p = pFrame->GetViewShell(); 2324 ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell,p); 2325 if(pViewSh!=NULL) 2326 { 2327 Window *pWin=pViewSh->GetWindow(); 2328 if(pWin!=NULL) pWin->GrabFocus(); 2329 } 2330 } 2331 2332 return sal_False; 2333 } 2334 if ( aDocument.IsInLinkUpdate() || aDocument.IsInInterpreter() ) 2335 { 2336 ErrorMessage(STR_CLOSE_ERROR_LINK); 2337 return sal_False; 2338 } 2339 2340 DoEnterHandler(); 2341 2342 // start 'Workbook_BeforeClose' VBA event handler for possible veto 2343 if( !IsInPrepareClose() ) 2344 { 2345 try 2346 { 2347 uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents( aDocument.GetVbaEventProcessor(), uno::UNO_SET_THROW ); 2348 uno::Sequence< uno::Any > aArgs; 2349 xVbaEvents->processVbaEvent( script::vba::VBAEventId::WORKBOOK_BEFORECLOSE, aArgs ); 2350 } 2351 catch( util::VetoException& ) 2352 { 2353 // if event processor throws VetoException, macro has vetoed close 2354 return sal_False; 2355 } 2356 catch( uno::Exception& ) 2357 { 2358 } 2359 } 2360 // end handler code 2361 2362 sal_uInt16 nRet = SfxObjectShell::PrepareClose( bUI, bForBrowsing ); 2363 if (nRet == sal_True) // sal_True = schliessen 2364 aDocument.DisableIdle(sal_True); // nicht mehr drin rumpfuschen !!! 2365 2366 return nRet; 2367 } 2368 2369 void ScDocShell::PrepareReload() 2370 { 2371 SfxObjectShell::PrepareReload(); // tut nichts? 2372 2373 // Das Disconnect von DDE-Links kann Reschedule ausloesen. 2374 // Wenn die DDE-Links erst im Dokument-dtor geloescht werden, kann beim Reload 2375 // aus diesem Reschedule das DDE-Link-Update fuer das neue Dokument ausgeloest 2376 // werden. Dabei verklemmt sicht dann irgendwas. 2377 // -> Beim Reload die DDE-Links des alten Dokuments vorher disconnecten 2378 2379 aDocument.DisconnectDdeLinks(); 2380 } 2381 2382 2383 String ScDocShell::GetOwnFilterName() // static 2384 { 2385 return String::CreateFromAscii(pFilterSc50); 2386 } 2387 2388 String ScDocShell::GetHtmlFilterName() 2389 { 2390 return String::CreateFromAscii(pFilterHtml); 2391 } 2392 2393 String ScDocShell::GetWebQueryFilterName() // static 2394 { 2395 return String::CreateFromAscii(pFilterHtmlWebQ); 2396 } 2397 2398 String ScDocShell::GetAsciiFilterName() // static 2399 { 2400 return String::CreateFromAscii(pFilterAscii); 2401 } 2402 2403 String ScDocShell::GetLotusFilterName() // static 2404 { 2405 return String::CreateFromAscii(pFilterLotus); 2406 } 2407 2408 String ScDocShell::GetDBaseFilterName() // static 2409 { 2410 return String::CreateFromAscii(pFilterDBase); 2411 } 2412 2413 String ScDocShell::GetDifFilterName() // static 2414 { 2415 return String::CreateFromAscii(pFilterDif); 2416 } 2417 2418 sal_Bool ScDocShell::HasAutomaticTableName( const String& rFilter ) // static 2419 { 2420 // sal_True for those filters that keep the default table name 2421 // (which is language specific) 2422 2423 return rFilter.EqualsAscii( pFilterAscii ) 2424 || rFilter.EqualsAscii( pFilterLotus ) 2425 || rFilter.EqualsAscii( pFilterExcel4 ) 2426 || rFilter.EqualsAscii( pFilterEx4Temp ) 2427 || rFilter.EqualsAscii( pFilterDBase ) 2428 || rFilter.EqualsAscii( pFilterDif ) 2429 || rFilter.EqualsAscii( pFilterSylk ) 2430 || rFilter.EqualsAscii( pFilterHtml ) 2431 || rFilter.EqualsAscii( pFilterRtf ); 2432 } 2433 2434 //================================================================== 2435 2436 #define __SCDOCSHELL_INIT \ 2437 aDocument ( SCDOCMODE_DOCUMENT, this ), \ 2438 aDdeTextFmt(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("TEXT"))), \ 2439 nPrtToScreenFactor( 1.0 ), \ 2440 pImpl ( new DocShell_Impl ), \ 2441 bHeaderOn ( sal_True ), \ 2442 bFooterOn ( sal_True ), \ 2443 bNoInformLost ( sal_True ), \ 2444 bIsEmpty ( sal_True ), \ 2445 bIsInUndo ( sal_False ), \ 2446 bDocumentModifiedPending( sal_False ), \ 2447 nDocumentLock ( 0 ), \ 2448 nCanUpdate (com::sun::star::document::UpdateDocMode::ACCORDING_TO_CONFIG), \ 2449 bUpdateEnabled ( sal_True ), \ 2450 pOldAutoDBRange ( NULL ), \ 2451 pDocHelper ( NULL ), \ 2452 pAutoStyleList ( NULL ), \ 2453 pPaintLockData ( NULL ), \ 2454 pOldJobSetup ( NULL ), \ 2455 pSolverSaveData ( NULL ), \ 2456 pSheetSaveData ( NULL ), \ 2457 pModificator ( NULL ) 2458 2459 //------------------------------------------------------------------ 2460 2461 ScDocShell::ScDocShell( const ScDocShell& rShell ) 2462 : SvRefBase(), 2463 SotObject(), 2464 SfxObjectShell( rShell.GetCreateMode() ), 2465 SfxListener(), 2466 __SCDOCSHELL_INIT 2467 { 2468 RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::ScDocShell" ); 2469 2470 SetPool( &SC_MOD()->GetPool() ); 2471 2472 bIsInplace = rShell.bIsInplace; 2473 2474 pDocFunc = new ScDocFunc(*this); 2475 2476 // SetBaseModel needs exception handling 2477 ScModelObj::CreateAndSet( this ); 2478 2479 StartListening(*this); 2480 SfxStyleSheetPool* pStlPool = aDocument.GetStyleSheetPool(); 2481 if (pStlPool) 2482 StartListening(*pStlPool); 2483 2484 GetPageOnFromPageStyleSet( NULL, 0, bHeaderOn, bFooterOn ); 2485 SetHelpId( HID_SCSHELL_DOCSH ); 2486 2487 // InitItems und CalcOutputFactor werden jetzt nach bei Load/ConvertFrom/InitNew gerufen 2488 } 2489 2490 //------------------------------------------------------------------ 2491 2492 ScDocShell::ScDocShell( const sal_uInt64 i_nSfxCreationFlags ) 2493 : SfxObjectShell( i_nSfxCreationFlags ) 2494 , __SCDOCSHELL_INIT 2495 { 2496 RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::ScDocShell" ); 2497 2498 SetPool( &SC_MOD()->GetPool() ); 2499 2500 bIsInplace = (GetCreateMode() == SFX_CREATE_MODE_EMBEDDED); 2501 // wird zurueckgesetzt, wenn nicht inplace 2502 2503 pDocFunc = new ScDocFunc(*this); 2504 2505 // SetBaseModel needs exception handling 2506 ScModelObj::CreateAndSet( this ); 2507 2508 StartListening(*this); 2509 SfxStyleSheetPool* pStlPool = aDocument.GetStyleSheetPool(); 2510 if (pStlPool) 2511 StartListening(*pStlPool); 2512 SetHelpId( HID_SCSHELL_DOCSH ); 2513 2514 aDocument.GetDBCollection()->SetRefreshHandler( 2515 LINK( this, ScDocShell, RefreshDBDataHdl ) ); 2516 2517 // InitItems und CalcOutputFactor werden jetzt nach bei Load/ConvertFrom/InitNew gerufen 2518 } 2519 2520 //------------------------------------------------------------------ 2521 2522 __EXPORT ScDocShell::~ScDocShell() 2523 { 2524 ResetDrawObjectShell(); // #55570# falls der Drawing-Layer noch versucht, darauf zuzugreifen 2525 2526 SfxStyleSheetPool* pStlPool = aDocument.GetStyleSheetPool(); 2527 if (pStlPool) 2528 EndListening(*pStlPool); 2529 EndListening(*this); 2530 2531 delete pAutoStyleList; 2532 2533 SfxApplication *pSfxApp = SFX_APP(); 2534 if ( pSfxApp->GetDdeService() ) // DDE vor Dokument loeschen 2535 pSfxApp->RemoveDdeTopic( this ); 2536 2537 delete pDocFunc; 2538 delete aDocument.mpUndoManager; 2539 aDocument.mpUndoManager = 0; 2540 delete pImpl; 2541 2542 delete pPaintLockData; 2543 2544 delete pOldJobSetup; // gesetzt nur bei Fehler in StartJob() 2545 2546 delete pSolverSaveData; 2547 delete pSheetSaveData; 2548 delete pOldAutoDBRange; 2549 2550 if (pModificator) 2551 { 2552 DBG_ERROR("The Modificator should not exist"); 2553 delete pModificator; 2554 } 2555 } 2556 2557 //------------------------------------------------------------------ 2558 2559 ::svl::IUndoManager* __EXPORT ScDocShell::GetUndoManager() 2560 { 2561 return aDocument.GetUndoManager(); 2562 } 2563 2564 void ScDocShell::SetModified( sal_Bool bModified ) 2565 { 2566 if ( SfxObjectShell::IsEnableSetModified() ) 2567 { 2568 SfxObjectShell::SetModified( bModified ); 2569 Broadcast( SfxSimpleHint( SFX_HINT_DOCCHANGED ) ); 2570 } 2571 } 2572 2573 2574 void ScDocShell::SetDocumentModified( sal_Bool bIsModified /* = sal_True */ ) 2575 { 2576 // BroadcastUno muss auch mit pPaintLockData sofort passieren 2577 //! auch bei SetDrawModified, wenn Drawing angebunden ist 2578 //! dann eigener Hint??? 2579 2580 if ( pPaintLockData && bIsModified ) 2581 { 2582 // #i115009# broadcast BCA_BRDCST_ALWAYS, so a component can read recalculated results 2583 // of RecalcModeAlways formulas (like OFFSET) after modifying cells 2584 aDocument.Broadcast( SC_HINT_DATACHANGED, BCA_BRDCST_ALWAYS, NULL ); 2585 aDocument.InvalidateTableArea(); // #i105279# needed here 2586 aDocument.BroadcastUno( SfxSimpleHint( SFX_HINT_DATACHANGED ) ); 2587 2588 pPaintLockData->SetModified(); // spaeter... 2589 return; 2590 } 2591 2592 SetDrawModified( bIsModified ); 2593 2594 if ( bIsModified ) 2595 { 2596 if ( aDocument.IsAutoCalcShellDisabled() ) 2597 SetDocumentModifiedPending( sal_True ); 2598 else 2599 { 2600 SetDocumentModifiedPending( sal_False ); 2601 aDocument.InvalidateStyleSheetUsage(); 2602 aDocument.InvalidateTableArea(); 2603 aDocument.InvalidateLastTableOpParams(); 2604 aDocument.Broadcast( SC_HINT_DATACHANGED, BCA_BRDCST_ALWAYS, NULL ); 2605 if ( aDocument.IsForcedFormulaPending() && aDocument.GetAutoCalc() ) 2606 aDocument.CalcFormulaTree( sal_True ); 2607 PostDataChanged(); 2608 2609 // Detective AutoUpdate: 2610 // Update if formulas were modified (DetectiveDirty) or the list contains 2611 // "Trace Error" entries (#75362# - Trace Error can look completely different 2612 // after changes to non-formula cells). 2613 2614 ScDetOpList* pList = aDocument.GetDetOpList(); 2615 if ( pList && ( aDocument.IsDetectiveDirty() || pList->HasAddError() ) && 2616 pList->Count() && !IsInUndo() && SC_MOD()->GetAppOptions().GetDetectiveAuto() ) 2617 { 2618 GetDocFunc().DetectiveRefresh(sal_True); // sal_True = caused by automatic update 2619 } 2620 aDocument.SetDetectiveDirty(sal_False); // always reset, also if not refreshed 2621 } 2622 2623 // #b6697848# notify UNO objects after BCA_BRDCST_ALWAYS etc. 2624 aDocument.BroadcastUno( SfxSimpleHint( SFX_HINT_DATACHANGED ) ); 2625 } 2626 } 2627 2628 // SetDrawModified - ohne Formel-Update 2629 // (Drawing muss auch beim normalen SetDocumentModified upgedated werden, 2630 // z.B. bei Tabelle loeschen etc.) 2631 2632 void ScDocShell::SetDrawModified( sal_Bool bIsModified /* = sal_True */ ) 2633 { 2634 sal_Bool bUpdate = ( bIsModified != IsModified() ); 2635 2636 SetModified( bIsModified ); 2637 2638 SfxBindings* pBindings = GetViewBindings(); 2639 if (bUpdate) 2640 { 2641 if (pBindings) 2642 { 2643 pBindings->Invalidate( SID_SAVEDOC ); 2644 pBindings->Invalidate( SID_DOC_MODIFIED ); 2645 } 2646 } 2647 2648 if (bIsModified) 2649 { 2650 if (pBindings) 2651 { 2652 // #i105960# Undo etc used to be volatile. 2653 // They always have to be invalidated, including drawing layer or row height changes 2654 // (but not while pPaintLockData is set). 2655 pBindings->Invalidate( SID_UNDO ); 2656 pBindings->Invalidate( SID_REDO ); 2657 pBindings->Invalidate( SID_REPEAT ); 2658 } 2659 2660 if ( aDocument.IsChartListenerCollectionNeedsUpdate() ) 2661 { 2662 aDocument.UpdateChartListenerCollection(); 2663 SFX_APP()->Broadcast(SfxSimpleHint( SC_HINT_DRAW_CHANGED )); // Navigator 2664 } 2665 SC_MOD()->AnythingChanged(); 2666 } 2667 } 2668 2669 void ScDocShell::SetInUndo(sal_Bool bSet) 2670 { 2671 bIsInUndo = bSet; 2672 } 2673 2674 2675 void ScDocShell::GetDocStat( ScDocStat& rDocStat ) 2676 { 2677 SfxPrinter* pPrinter = GetPrinter(); 2678 2679 aDocument.GetDocStat( rDocStat ); 2680 rDocStat.nPageCount = 0; 2681 2682 if ( pPrinter ) 2683 for ( SCTAB i=0; i<rDocStat.nTableCount; i++ ) 2684 rDocStat.nPageCount = sal::static_int_cast<sal_uInt16>( rDocStat.nPageCount + 2685 (sal_uInt16) ScPrintFunc( this, pPrinter, i ).GetTotalPages() ); 2686 } 2687 2688 2689 SfxDocumentInfoDialog* __EXPORT ScDocShell::CreateDocumentInfoDialog( 2690 Window *pParent, const SfxItemSet &rSet ) 2691 { 2692 SfxDocumentInfoDialog* pDlg = new SfxDocumentInfoDialog( pParent, rSet ); 2693 ScDocShell* pDocSh = PTR_CAST(ScDocShell,SfxObjectShell::Current()); 2694 2695 //nur mit Statistik, wenn dieses Doc auch angezeigt wird, nicht 2696 //aus dem Doc-Manager 2697 2698 if( pDocSh == this ) 2699 { 2700 ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create(); 2701 DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001 2702 ::CreateTabPage ScDocStatPageCreate = pFact->GetTabPageCreatorFunc( RID_SCPAGE_STAT ); 2703 DBG_ASSERT(ScDocStatPageCreate, "Tabpage create fail!");//CHINA001 2704 pDlg->AddTabPage( 42, 2705 ScGlobal::GetRscString( STR_DOC_STAT ), 2706 ScDocStatPageCreate, 2707 NULL); 2708 //CHINA001 pDlg->AddTabPage( 42, 2709 //CHINA001 ScGlobal::GetRscString( STR_DOC_STAT ), 2710 //CHINA001 ScDocStatPage::Create, 2711 //CHINA001 NULL ); 2712 } 2713 return pDlg; 2714 } 2715 2716 Window* ScDocShell::GetActiveDialogParent() 2717 { 2718 ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell(); 2719 if ( pViewSh ) 2720 return pViewSh->GetDialogParent(); 2721 else 2722 return Application::GetDefDialogParent(); 2723 } 2724 2725 void ScDocShell::SetSolverSaveData( const ScOptSolverSave& rData ) 2726 { 2727 delete pSolverSaveData; 2728 pSolverSaveData = new ScOptSolverSave( rData ); 2729 } 2730 2731 ScSheetSaveData* ScDocShell::GetSheetSaveData() 2732 { 2733 if (!pSheetSaveData) 2734 pSheetSaveData = new ScSheetSaveData; 2735 2736 return pSheetSaveData; 2737 } 2738 2739 void ScDocShell::UseSheetSaveEntries() 2740 { 2741 if (pSheetSaveData) 2742 { 2743 pSheetSaveData->UseSaveEntries(); // use positions from saved file for next saving 2744 2745 bool bHasEntries = false; 2746 SCTAB nTabCount = aDocument.GetTableCount(); 2747 SCTAB nTab; 2748 for (nTab = 0; nTab < nTabCount; ++nTab) 2749 if (pSheetSaveData->HasStreamPos(nTab)) 2750 bHasEntries = true; 2751 2752 if (!bHasEntries) 2753 { 2754 // if no positions were set (for example, export to other format), 2755 // reset all "valid" flags 2756 2757 for (nTab = 0; nTab < nTabCount; ++nTab) 2758 if (aDocument.IsStreamValid(nTab)) 2759 aDocument.SetStreamValid(nTab, sal_False); 2760 } 2761 } 2762 } 2763 2764 // --- ScDocShellModificator ------------------------------------------ 2765 2766 ScDocShellModificator::ScDocShellModificator( ScDocShell& rDS ) 2767 : 2768 rDocShell( rDS ), 2769 aProtector( rDS.GetDocument()->GetRefreshTimerControlAddress() ) 2770 { 2771 ScDocument* pDoc = rDocShell.GetDocument(); 2772 bAutoCalcShellDisabled = pDoc->IsAutoCalcShellDisabled(); 2773 bIdleDisabled = pDoc->IsIdleDisabled(); 2774 pDoc->SetAutoCalcShellDisabled( sal_True ); 2775 pDoc->DisableIdle( sal_True ); 2776 } 2777 2778 2779 ScDocShellModificator::~ScDocShellModificator() 2780 { 2781 ScDocument* pDoc = rDocShell.GetDocument(); 2782 pDoc->SetAutoCalcShellDisabled( bAutoCalcShellDisabled ); 2783 if ( !bAutoCalcShellDisabled && rDocShell.IsDocumentModifiedPending() ) 2784 rDocShell.SetDocumentModified(); // last one shuts off the lights 2785 pDoc->DisableIdle( bIdleDisabled ); 2786 } 2787 2788 2789 void ScDocShellModificator::SetDocumentModified() 2790 { 2791 ScDocument* pDoc = rDocShell.GetDocument(); 2792 if ( !pDoc->IsImportingXML() ) 2793 { 2794 // AutoCalcShellDisabled temporaer restaurieren 2795 sal_Bool bDisabled = pDoc->IsAutoCalcShellDisabled(); 2796 pDoc->SetAutoCalcShellDisabled( bAutoCalcShellDisabled ); 2797 rDocShell.SetDocumentModified(); 2798 pDoc->SetAutoCalcShellDisabled( bDisabled ); 2799 } 2800 else 2801 { 2802 // uno broadcast is necessary for api to work 2803 // -> must also be done during xml import 2804 pDoc->BroadcastUno( SfxSimpleHint( SFX_HINT_DATACHANGED ) ); 2805 } 2806 } 2807 2808 //<!--Added by PengYunQuan for Validity Cell Range Picker 2809 sal_Bool ScDocShell::AcceptStateUpdate() const 2810 { 2811 if( SfxObjectShell::AcceptStateUpdate() ) 2812 return sal_True; 2813 2814 if( SC_MOD()->Find1RefWindow( SFX_APP()->GetTopWindow() ) ) 2815 return sal_True; 2816 2817 return sal_False; 2818 } 2819 //-->Added by PengYunQuan for Validity Cell Range Picker 2820 2821 2822 bool ScDocShell::IsChangeRecording() const 2823 { 2824 ScChangeTrack* pChangeTrack = aDocument.GetChangeTrack(); 2825 return pChangeTrack != NULL; 2826 } 2827 2828 2829 bool ScDocShell::HasChangeRecordProtection() const 2830 { 2831 bool bRes = false; 2832 ScChangeTrack* pChangeTrack = aDocument.GetChangeTrack(); 2833 if (pChangeTrack) 2834 bRes = pChangeTrack->IsProtected(); 2835 return bRes; 2836 } 2837 2838 2839 void ScDocShell::SetChangeRecording( bool bActivate ) 2840 { 2841 bool bOldChangeRecording = IsChangeRecording(); 2842 2843 if (bActivate) 2844 { 2845 aDocument.StartChangeTracking(); 2846 ScChangeViewSettings aChangeViewSet; 2847 aChangeViewSet.SetShowChanges(sal_True); 2848 aDocument.SetChangeViewSettings(aChangeViewSet); 2849 } 2850 else 2851 { 2852 aDocument.EndChangeTracking(); 2853 PostPaintGridAll(); 2854 } 2855 2856 if (bOldChangeRecording != IsChangeRecording()) 2857 { 2858 UpdateAcceptChangesDialog(); 2859 // Slots invalidieren 2860 SfxBindings* pBindings = GetViewBindings(); 2861 if (pBindings) 2862 pBindings->InvalidateAll(sal_False); 2863 } 2864 } 2865 2866 2867 bool ScDocShell::SetProtectionPassword( const String &rNewPassword ) 2868 { 2869 bool bRes = false; 2870 ScChangeTrack* pChangeTrack = aDocument.GetChangeTrack(); 2871 if (pChangeTrack) 2872 { 2873 sal_Bool bProtected = pChangeTrack->IsProtected(); 2874 2875 if (rNewPassword.Len()) 2876 { 2877 // when password protection is applied change tracking must always be active 2878 SetChangeRecording( true ); 2879 2880 ::com::sun::star::uno::Sequence< sal_Int8 > aProtectionHash; 2881 SvPasswordHelper::GetHashPassword( aProtectionHash, rNewPassword ); 2882 pChangeTrack->SetProtection( aProtectionHash ); 2883 } 2884 else 2885 { 2886 pChangeTrack->SetProtection( ::com::sun::star::uno::Sequence< sal_Int8 >() ); 2887 } 2888 bRes = true; 2889 2890 if ( bProtected != pChangeTrack->IsProtected() ) 2891 { 2892 UpdateAcceptChangesDialog(); 2893 SetDocumentModified(); 2894 } 2895 } 2896 2897 return bRes; 2898 } 2899 2900 2901 bool ScDocShell::GetProtectionHash( /*out*/ ::com::sun::star::uno::Sequence< sal_Int8 > &rPasswordHash ) 2902 { 2903 bool bRes = false; 2904 ScChangeTrack* pChangeTrack = aDocument.GetChangeTrack(); 2905 if (pChangeTrack && pChangeTrack->IsProtected()) 2906 { 2907 rPasswordHash = pChangeTrack->GetProtection(); 2908 bRes = true; 2909 } 2910 return bRes; 2911 } 2912 2913 2914