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