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