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