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