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