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