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