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