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