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