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