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