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