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