1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <config_features.h>
24 #include "scitems.hxx"
25 #include <editeng/justifyitem.hxx>
26 #include <comphelper/classids.hxx>
27 #include <vcl/msgbox.hxx>
28 #include <vcl/virdev.hxx>
29 #include <vcl/waitobj.hxx>
30 #include <svl/PasswordHelper.hxx>
31 #include <sfx2/app.hxx>
32 #include <sfx2/bindings.hxx>
33 #include <sfx2/dinfdlg.hxx>
34 #include <sfx2/docfile.hxx>
35 #include <sfx2/fcontnr.hxx>
36 #include <sfx2/objface.hxx>
37 #include <sfx2/viewfrm.hxx>
38 #include <svl/documentlockfile.hxx>
39 #include <svl/sharecontrolfile.hxx>
40 #include <svl/urihelper.hxx>
41 #include "chgtrack.hxx"
42 #include "chgviset.hxx"
43 #include <com/sun/star/awt/Key.hpp>
44 #include <com/sun/star/awt/KeyModifier.hpp>
45 #include <com/sun/star/container/XContentEnumerationAccess.hpp>
46 #include <com/sun/star/document/UpdateDocMode.hpp>
47 #include <com/sun/star/script/vba/VBAEventId.hpp>
48 #include <com/sun/star/script/vba/XVBAEventProcessor.hpp>
49 #include <com/sun/star/sheet/XSpreadsheetView.hpp>
50 #include <com/sun/star/task/XJob.hpp>
51 #include <com/sun/star/ui/theModuleUIConfigurationManagerSupplier.hpp>
52 #include <com/sun/star/ui/XAcceleratorConfiguration.hpp>
53 #include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
54 #include <com/sun/star/sheet/XSpreadsheet.hpp>
55 #include <com/sun/star/container/XIndexAccess.hpp>
56 #include <com/sun/star/table/XTableChartsSupplier.hpp>
57 #include <com/sun/star/table/XTableCharts.hpp>
58 #include <com/sun/star/table/XTableChart.hpp>
59 #include <com/sun/star/chart2/XChartDocument.hpp>
60 #include <com/sun/star/document/XEmbeddedObjectSupplier.hpp>
61 #include <com/sun/star/frame/XStorable2.hpp>
62 #include <com/sun/star/frame/Desktop.hpp>
64 #include "scabstdlg.hxx"
65 #include <sot/formats.hxx>
67 #include "formulacell.hxx"
72 #include "tabvwsh.hxx"
73 #include "docfunc.hxx"
74 #include "imoptdlg.hxx"
76 #include "scresid.hxx"
78 #include "globstr.hrc"
79 #include "scerrors.hxx"
81 #include "stlpool.hxx"
82 #include "autostyl.hxx"
84 #include "asciiopt.hxx"
85 #include "waitoff.hxx"
86 #include "docpool.hxx"
87 #include "progress.hxx"
88 #include "pntlock.hxx"
90 #include "appoptio.hxx"
91 #include "detdata.hxx"
92 #include "printfun.hxx"
93 #include "dociter.hxx"
94 #include "cellform.hxx"
95 #include "chartlis.hxx"
97 #include "xmlwrap.hxx"
98 #include "drwlayer.hxx"
99 #include "refreshtimer.hxx"
100 #include "dbdata.hxx"
101 #include "scextopt.hxx"
102 #include "compiler.hxx"
103 #include "cfgids.hxx"
104 #include "warnpassword.hxx"
105 #include "optsolver.hxx"
106 #include "sheetdata.hxx"
107 #include "tabprotection.hxx"
108 #include "docparam.hxx"
109 #include "docshimp.hxx"
110 #include "sizedev.hxx"
111 #include "refreshtimerprotector.hxx"
113 #include <officecfg/Office/Calc.hxx>
114 #include <comphelper/processfactory.hxx>
115 #include <comphelper/string.hxx>
116 #include <unotools/configmgr.hxx>
117 #include "uiitems.hxx"
118 #include "cellsuno.hxx"
119 #include "dpobject.hxx"
120 #include "markdata.hxx"
121 #include "orcusfilters.hxx"
122 #include <datastream.hxx>
123 #include <documentlinkmgr.hxx>
124 #include <refupdatecontext.hxx>
126 #include <config_telepathy.h>
129 #include "sccollaboration.hxx"
133 #include <boost/shared_ptr.hpp>
135 using namespace com::sun::star
;
136 using ::com::sun::star::uno::Reference
;
137 using ::com::sun::star::uno::UNO_QUERY
;
138 using ::com::sun::star::lang::XMultiServiceFactory
;
139 using ::boost::shared_ptr
;
142 // STATIC DATA -----------------------------------------------------------
144 // Filter names (like in sclib.cxx)
146 static const sal_Char pFilterSc50
[] = "StarCalc 5.0";
147 static const sal_Char pFilterSc40
[] = "StarCalc 4.0";
148 static const sal_Char pFilterSc30
[] = "StarCalc 3.0";
149 static const sal_Char pFilterSc10
[] = "StarCalc 1.0";
150 static const sal_Char pFilterXML
[] = "StarOffice XML (Calc)";
151 static const sal_Char pFilterAscii
[] = "Text - txt - csv (StarCalc)";
152 static const sal_Char pFilterLotus
[] = "Lotus";
153 static const sal_Char pFilterQPro6
[] = "Quattro Pro 6.0";
154 static const sal_Char pFilterExcel4
[] = "MS Excel 4.0";
155 static const sal_Char pFilterEx4Temp
[] = "MS Excel 4.0 Vorlage/Template";
156 static const sal_Char pFilterExcel5
[] = "MS Excel 5.0/95";
157 static const sal_Char pFilterEx5Temp
[] = "MS Excel 5.0/95 Vorlage/Template";
158 static const sal_Char pFilterExcel95
[] = "MS Excel 95";
159 static const sal_Char pFilterEx95Temp
[] = "MS Excel 95 Vorlage/Template";
160 static const sal_Char pFilterExcel97
[] = "MS Excel 97";
161 static const sal_Char pFilterEx97Temp
[] = "MS Excel 97 Vorlage/Template";
162 static const sal_Char pFilterDBase
[] = "dBase";
163 static const sal_Char pFilterDif
[] = "DIF";
164 static const sal_Char pFilterSylk
[] = "SYLK";
165 static const sal_Char pFilterHtml
[] = "HTML (StarCalc)";
166 static const sal_Char pFilterHtmlWebQ
[] = "calc_HTML_WebQuery";
167 static const sal_Char pFilterRtf
[] = "Rich Text Format (StarCalc)";
170 #include "scslots.hxx"
173 SFX_IMPL_INTERFACE(ScDocShell
,SfxObjectShell
, ScResId(SCSTR_DOCSHELL
))
175 void ScDocShell::InitInterface_Impl()
179 // GlobalName of the current version:
180 SFX_IMPL_OBJECTFACTORY( ScDocShell
, SvGlobalName(SO3_SC_CLASSID
), SFXOBJECTSHELL_STD_NORMAL
, "scalc" )
182 TYPEINIT1( ScDocShell
, SfxObjectShell
); // SfxInPlaceObject: No TypeInfo?
184 void ScDocShell::FillClass( SvGlobalName
* pClassName
,
186 OUString
* /* pAppName */,
187 OUString
* pFullTypeName
,
188 OUString
* pShortTypeName
,
189 sal_Int32 nFileFormat
,
190 bool bTemplate
/* = false */) const
192 if ( nFileFormat
== SOFFICE_FILEFORMAT_60
)
194 *pClassName
= SvGlobalName( SO3_SC_CLASSID_60
);
195 *pFormat
= SOT_FORMATSTR_ID_STARCALC_60
;
196 *pFullTypeName
= OUString( ScResId( SCSTR_LONG_SCDOC_NAME
) );
197 *pShortTypeName
= OUString( ScResId( SCSTR_SHORT_SCDOC_NAME
) );
199 else if ( nFileFormat
== SOFFICE_FILEFORMAT_8
)
201 *pClassName
= SvGlobalName( SO3_SC_CLASSID_60
);
202 *pFormat
= bTemplate
? SOT_FORMATSTR_ID_STARCALC_8_TEMPLATE
: SOT_FORMATSTR_ID_STARCALC_8
;
203 *pFullTypeName
= "calc8";
204 *pShortTypeName
= ScResId(SCSTR_SHORT_SCDOC_NAME
).toString();
208 OSL_FAIL("Which version?");
212 void ScDocShell::DoEnterHandler()
214 ScTabViewShell
* pViewSh
= ScTabViewShell::GetActiveViewShell();
216 if (pViewSh
->GetViewData()->GetDocShell() == this)
217 SC_MOD()->InputEnterHandler();
220 SCTAB
ScDocShell::GetSaveTab()
223 ScTabViewShell
* pSh
= GetBestViewShell();
226 const ScMarkData
& rMark
= pSh
->GetViewData()->GetMarkData();
227 nTab
= rMark
.GetFirstSelected();
232 sal_uInt16
ScDocShell::GetHiddenInformationState( sal_uInt16 nStates
)
234 // get global state like HIDDENINFORMATION_DOCUMENTVERSIONS
235 sal_uInt16 nState
= SfxObjectShell::GetHiddenInformationState( nStates
);
237 if ( nStates
& HIDDENINFORMATION_RECORDEDCHANGES
)
239 if ( aDocument
.GetChangeTrack() && aDocument
.GetChangeTrack()->GetFirst() )
240 nState
|= HIDDENINFORMATION_RECORDEDCHANGES
;
242 if ( nStates
& HIDDENINFORMATION_NOTES
)
244 SCTAB nTableCount
= aDocument
.GetTableCount();
246 for (SCTAB nTab
= 0; nTab
< nTableCount
&& !bFound
; ++nTab
)
248 if (aDocument
.HasTabNotes(nTab
)) //TODO:
253 nState
|= HIDDENINFORMATION_NOTES
;
259 void ScDocShell::BeforeXMLLoading()
261 aDocument
.EnableIdle(false);
263 // prevent unnecessary broadcasts and updates
264 OSL_ENSURE(pModificator
== NULL
, "The Modificator should not exist");
265 pModificator
= new ScDocShellModificator( *this );
267 aDocument
.SetImportingXML( true );
268 aDocument
.EnableExecuteLink( false ); // #i101304# to be safe, prevent nested loading from external references
269 aDocument
.EnableUndo( false );
270 // prevent unnecessary broadcasts and "half way listeners"
271 aDocument
.SetInsertingFromOtherDoc( true );
274 void ScDocShell::AfterXMLLoading(bool bRet
)
276 if (GetCreateMode() != SFX_CREATE_MODE_ORGANIZER
)
279 // don't prevent establishing of listeners anymore
280 aDocument
.SetInsertingFromOtherDoc( false );
283 ScChartListenerCollection
* pChartListener
= aDocument
.GetChartListenerCollection();
285 pChartListener
->UpdateDirtyCharts();
287 // #95582#; set the table names of linked tables to the new path
288 SCTAB nTabCount
= aDocument
.GetTableCount();
289 for (SCTAB i
= 0; i
< nTabCount
; ++i
)
291 if (aDocument
.IsLinked( i
))
294 aDocument
.GetName(i
, aName
);
295 OUString aLinkTabName
= aDocument
.GetLinkTab(i
);
296 sal_Int32 nLinkTabNameLength
= aLinkTabName
.getLength();
297 sal_Int32 nNameLength
= aName
.getLength();
298 if (nLinkTabNameLength
< nNameLength
)
301 // remove the quottes on begin and end of the docname and restore the escaped quotes
302 const sal_Unicode
* pNameBuffer
= aName
.getStr();
303 if ( *pNameBuffer
== '\'' && // all docnames have to have a ' character on the first pos
304 ScGlobal::UnicodeStrChr( pNameBuffer
, SC_COMPILER_FILE_TAB_SEP
) )
306 OUStringBuffer aDocURLBuffer
;
307 bool bQuote
= true; // Document name is always quoted
309 while ( bQuote
&& *pNameBuffer
)
311 if ( *pNameBuffer
== '\'' && *(pNameBuffer
-1) != '\\' )
313 else if( !(*pNameBuffer
== '\\' && *(pNameBuffer
+1) == '\'') )
314 aDocURLBuffer
.append(*pNameBuffer
); // If escaped quote: only quote in the name
319 if( *pNameBuffer
== SC_COMPILER_FILE_TAB_SEP
) // after the last quote of the docname should be the # char
321 sal_Int32 nIndex
= nNameLength
- nLinkTabNameLength
;
322 INetURLObject
aINetURLObject(aDocURLBuffer
.makeStringAndClear());
323 if(aName
.match( aLinkTabName
, nIndex
) &&
324 (aName
[nIndex
- 1] == '#') && // before the table name should be the # char
325 !aINetURLObject
.HasError()) // the docname should be a valid URL
327 aName
= ScGlobal::GetDocTabName( aDocument
.GetLinkDoc( i
), aDocument
.GetLinkTab( i
) );
328 aDocument
.RenameTab(i
, aName
, true, true);
330 // else; nothing has to happen, because it is a user given name
332 // else; nothing has to happen, because it is a user given name
334 // else; nothing has to happen, because it is a user given name
336 // else; nothing has to happen, because it is a user given name
340 // #i94570# DataPilot table names have to be unique, or the tables can't be accessed by API.
341 // If no name (or an invalid name, skipped in ScXMLDataPilotTableContext::EndElement) was set, create a new name.
342 ScDPCollection
* pDPCollection
= aDocument
.GetDPCollection();
345 size_t nDPCount
= pDPCollection
->GetCount();
346 for (size_t nDP
=0; nDP
<nDPCount
; ++nDP
)
348 ScDPObject
* pDPObj
= (*pDPCollection
)[nDP
];
349 if (pDPObj
->GetName().isEmpty())
350 pDPObj
->SetName( pDPCollection
->CreateNewName() );
356 aDocument
.SetInsertingFromOtherDoc( false );
358 aDocument
.SetImportingXML( false );
359 aDocument
.EnableExecuteLink( true );
360 aDocument
.EnableUndo( true );
365 bool bRecalcState
= aDocument
.GetHardRecalcState();
366 //temporarily set hard-recalc to prevent calling ScFormulaCell::Notify()
367 //which will set the cells dirty.
368 aDocument
.SetHardRecalcState(true);
370 aDocument
.SetHardRecalcState(bRecalcState
);
375 OSL_FAIL("The Modificator should exist");
378 aDocument
.EnableIdle(true);
383 class LoadMediumGuard
386 explicit LoadMediumGuard(ScDocument
* pDoc
) :
389 mpDoc
->SetLoadingMedium(true);
394 mpDoc
->SetLoadingMedium(false);
400 void processDataStream( ScDocShell
& rShell
, const sc::ImportPostProcessData
& rData
)
402 if (!rData
.mpDataStream
)
405 const sc::ImportPostProcessData::DataStream
& r
= *rData
.mpDataStream
;
406 if (!r
.maRange
.IsValid())
409 // Break the streamed range into the top range and the height limit. A
410 // height limit of 0 means unlimited i.e. the streamed data will go all
411 // the way to the last row.
413 ScRange aTopRange
= r
.maRange
;
414 aTopRange
.aEnd
.SetRow(aTopRange
.aStart
.Row());
415 sal_Int32 nLimit
= r
.maRange
.aEnd
.Row() - r
.maRange
.aStart
.Row() + 1;
416 if (r
.maRange
.aEnd
.Row() == MAXROW
)
420 sc::DataStream::MoveType eMove
=
421 r
.meInsertPos
== sc::ImportPostProcessData::DataStream::InsertTop
?
422 sc::DataStream::MOVE_DOWN
: sc::DataStream::RANGE_DOWN
;
424 sc::DataStream
* pStrm
= new sc::DataStream(&rShell
, r
.maURL
, aTopRange
, nLimit
, eMove
, 0);
425 pStrm
->SetRefreshOnEmptyLine(r
.mbRefreshOnEmpty
);
426 sc::DocumentLinkManager
& rMgr
= rShell
.GetDocument()->GetDocLinkManager();
427 rMgr
.setDataStream(pStrm
);
432 bool ScDocShell::LoadXML( SfxMedium
* pLoadMedium
, const ::com::sun::star::uno::Reference
< ::com::sun::star::embed::XStorage
>& xStor
)
434 LoadMediumGuard
aLoadGuard(&aDocument
);
436 // MacroCallMode is no longer needed, state is kept in SfxObjectShell now
438 // no Seek(0) here - always loading from storage, GetInStream must not be called
442 ScXMLImportWrapper
aImport(*this, pLoadMedium
, xStor
);
445 ErrCode nError
= ERRCODE_NONE
;
446 aDocument
.EnableAdjustHeight(false);
447 if (GetCreateMode() == SFX_CREATE_MODE_ORGANIZER
)
448 bRet
= aImport
.Import(ScXMLImportWrapper::STYLES
, nError
);
450 bRet
= aImport
.Import(ScXMLImportWrapper::ALL
, nError
);
453 pLoadMedium
->SetError( nError
, OUString( OSL_LOG_PREFIX
) );
455 processDataStream(*this, aImport
.GetImportPostProcessData());
457 //if the document was not generated by LibreOffice, do hard recalc in case some other document
458 //generator saved cached formula results that differ from LibreOffice's calculated results or
459 //did not use cached formula results.
460 uno::Reference
<document::XDocumentPropertiesSupplier
> xDPS(GetModel(), uno::UNO_QUERY_THROW
);
461 uno::Reference
<document::XDocumentProperties
> xDocProps
= xDPS
->getDocumentProperties();
463 Reference
<uno::XComponentContext
> xContext
= comphelper::getProcessComponentContext();
464 ScRecalcOptions nRecalcMode
=
465 static_cast<ScRecalcOptions
>(officecfg::Office::Calc::Formula::Load::ODFRecalcMode::get(xContext
));
467 bool bHardRecalc
= false;
468 if (nRecalcMode
== RECALC_ASK
)
470 OUString
sProductName(utl::ConfigManager::getProductName());
471 if (aDocument
.IsUserInteractionEnabled() && xDocProps
->getGenerator().indexOf(sProductName
) == -1)
473 // Generator is not LibreOffice. Ask if the user wants to perform
474 // full re-calculation.
476 GetActiveDialogParent(), WinBits(WB_YES_NO
| WB_DEF_YES
),
477 ScGlobal::GetRscString(STR_QUERY_FORMULA_RECALC_ONLOAD_ODS
));
478 aBox
.SetCheckBoxText(ScGlobal::GetRscString(STR_ALWAYS_PERFORM_SELECTED
));
480 bHardRecalc
= aBox
.Execute() == RET_YES
;
482 if (aBox
.GetCheckBoxState())
484 // Always perform selected action in the future.
485 boost::shared_ptr
< comphelper::ConfigurationChanges
> batch( comphelper::ConfigurationChanges::create() );
486 officecfg::Office::Calc::Formula::Load::ODFRecalcMode::set(sal_Int32(0), batch
);
487 ScFormulaOptions aOpt
= SC_MOD()->GetFormulaOptions();
488 aOpt
.SetODFRecalcOptions(bHardRecalc
? RECALC_ALWAYS
: RECALC_NEVER
);
489 /* XXX is this really supposed to set the ScModule options?
490 * Not the ScDocShell options? */
491 SC_MOD()->SetFormulaOptions(aOpt
);
497 else if (nRecalcMode
== RECALC_ALWAYS
)
504 // still need to recalc volatile formula cells.
505 aDocument
.Broadcast(ScHint(SC_HINT_DATACHANGED
, BCA_BRDCST_ALWAYS
));
508 AfterXMLLoading(bRet
);
510 aDocument
.EnableAdjustHeight(true);
514 bool ScDocShell::SaveXML( SfxMedium
* pSaveMedium
, const ::com::sun::star::uno::Reference
< ::com::sun::star::embed::XStorage
>& xStor
)
516 aDocument
.EnableIdle(false);
518 ScXMLImportWrapper
aImport(*this, pSaveMedium
, xStor
);
520 if (GetCreateMode() != SFX_CREATE_MODE_ORGANIZER
)
521 bRet
= aImport
.Export(false);
523 bRet
= aImport
.Export(true);
525 aDocument
.EnableIdle(true);
530 bool ScDocShell::SaveCurrentChart( SfxMedium
& rMedium
)
537 uno::Reference
< lang::XComponent
> xCurrentComponent
= frame::Desktop::create( comphelper::getProcessComponentContext() )->getCurrentComponent();
539 uno::Reference
< frame::XStorable2
> xStorable( xCurrentComponent
, uno::UNO_QUERY_THROW
);
541 uno::Reference
< frame::XModel
> xChartDoc ( xCurrentComponent
, uno::UNO_QUERY_THROW
);
543 ScXMLChartExportWrapper
aExport( xChartDoc
, rMedium
);
544 bRet
= aExport
.Export();
548 SAL_WARN("sc", "exception thrown while saving chart. Bug!!!");
553 bool ScDocShell::Load( SfxMedium
& rMedium
)
555 LoadMediumGuard
aLoadGuard(&aDocument
);
556 ScRefreshTimerProtector
aProt( aDocument
.GetRefreshTimerControlAddress() );
558 // only the latin script language is loaded
559 // -> initialize the others from options (before loading)
562 GetUndoManager()->Clear();
564 bool bRet
= SfxObjectShell::Load( rMedium
);
569 SFX_ITEMSET_ARG( rMedium
.GetItemSet(), pUpdateDocItem
, SfxUInt16Item
, SID_UPDATEDOCMODE
, false);
570 nCanUpdate
= pUpdateDocItem
? pUpdateDocItem
->GetValue() : com::sun::star::document::UpdateDocMode::NO_UPDATE
;
574 // prepare a valid document for XML filter
575 // (for ConvertFrom, InitNew is called before)
576 aDocument
.MakeTable(0);
577 aDocument
.GetStyleSheetPool()->CreateStandardStyles();
578 aDocument
.UpdStlShtPtrsFrmNms();
580 bRet
= LoadXML( &rMedium
, NULL
);
584 if (!bRet
&& !rMedium
.GetError())
585 rMedium
.SetError( SVSTREAM_FILEFORMAT_ERROR
, OUString( OSL_LOG_PREFIX
) );
587 if (rMedium
.GetError())
588 SetError( rMedium
.GetError(), OUString( OSL_LOG_PREFIX
) );
593 // invalidate eventually temporary table areas
595 aDocument
.InvalidateTableArea();
598 FinishedLoading( SFX_LOADED_MAINDOCUMENT
| SFX_LOADED_IMAGES
);
602 void ScDocShell::Notify( SfxBroadcaster
&, const SfxHint
& rHint
)
604 if (rHint
.ISA(ScTablesHint
) )
606 const ScTablesHint
& rScHint
= static_cast< const ScTablesHint
& >( rHint
);
607 if (rScHint
.GetId() == SC_TAB_INSERTED
)
609 uno::Reference
< script::vba::XVBAEventProcessor
> xVbaEvents
= aDocument
.GetVbaEventProcessor();
610 if ( xVbaEvents
.is() ) try
612 uno::Sequence
< uno::Any
> aArgs( 1 );
613 aArgs
[0] <<= rScHint
.GetTab1();
614 xVbaEvents
->processVbaEvent( script::vba::VBAEventId::WORKBOOK_NEWSHEET
, aArgs
);
616 catch( uno::Exception
& )
622 if (rHint
.ISA(SfxSimpleHint
)) // Without parameter
624 sal_uLong nSlot
= ((const SfxSimpleHint
&)rHint
).GetId();
627 case SFX_HINT_TITLECHANGED
:
628 aDocument
.SetName( SfxShell::GetName() );
629 // RegisterNewTargetNames gibts nicht mehr
630 SFX_APP()->Broadcast(SfxSimpleHint( SC_HINT_DOCNAME_CHANGED
)); // Navigator
634 else if (rHint
.ISA(SfxStyleSheetHint
)) // Template changed
635 NotifyStyle((const SfxStyleSheetHint
&) rHint
);
636 else if (rHint
.ISA(ScAutoStyleHint
))
638 //! direct call for AutoStyles
640 // this is called synchronously from ScInterpreter::ScStyle,
641 // modifying the document must be asynchronous
642 // (handled by AddInitial)
644 ScAutoStyleHint
& rStlHint
= (ScAutoStyleHint
&)rHint
;
645 ScRange aRange
= rStlHint
.GetRange();
646 OUString aName1
= rStlHint
.GetStyle1();
647 OUString aName2
= rStlHint
.GetStyle2();
648 sal_uInt32 nTimeout
= rStlHint
.GetTimeout();
651 pAutoStyleList
= new ScAutoStyleList(this);
652 pAutoStyleList
->AddInitial( aRange
, aName1
, nTimeout
, aName2
);
654 else if ( rHint
.ISA( SfxEventHint
) )
656 sal_uLong nEventId
= ((SfxEventHint
&)rHint
).GetEventId();
659 case SFX_EVENT_LOADFINISHED
:
661 #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
662 // the readonly documents should not be opened in shared mode
663 if ( HasSharedXMLFlagSet() && !SC_MOD()->IsInSharedDocLoading() && !IsReadOnly() )
665 if ( SwitchToShared( true, false ) )
667 ScViewData
* pViewData
= GetViewData();
668 ScTabView
* pTabView
= ( pViewData
? dynamic_cast< ScTabView
* >( pViewData
->GetView() ) : NULL
);
671 pTabView
->UpdateLayerLocks();
676 // switching to shared mode has failed, the document should be opened readonly
677 // TODO/LATER: And error message should be shown here probably
678 SetReadOnlyUI( true );
684 case SFX_EVENT_VIEWCREATED
:
686 #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
687 if ( IsDocShared() && !SC_MOD()->IsInSharedDocLoading() )
689 ScAppOptions aAppOptions
= SC_MOD()->GetAppOptions();
690 if ( aAppOptions
.GetShowSharedDocumentWarning() )
692 WarningBox
aBox( GetActiveDialogParent(), WinBits( WB_OK
),
693 ScGlobal::GetRscString( STR_SHARED_DOC_WARNING
) );
694 aBox
.SetDefaultCheckBoxText();
696 bool bChecked
= aBox
.GetCheckBoxState();
699 aAppOptions
.SetShowSharedDocumentWarning( !bChecked
);
700 SC_MOD()->SetAppOptions( aAppOptions
);
707 uno::Reference
< uno::XComponentContext
> xContext(
708 comphelper::getProcessComponentContext() );
709 uno::Reference
< lang::XMultiServiceFactory
> xServiceManager(
710 xContext
->getServiceManager(),
711 uno::UNO_QUERY_THROW
);
712 uno::Reference
< container::XContentEnumerationAccess
> xEnumAccess( xServiceManager
, uno::UNO_QUERY_THROW
);
713 uno::Reference
< container::XEnumeration
> xEnum
= xEnumAccess
->createContentEnumeration(
714 OUString( "com.sun.star.sheet.SpreadsheetDocumentJob" ) );
717 while ( xEnum
->hasMoreElements() )
719 uno::Any aAny
= xEnum
->nextElement();
720 uno::Reference
< lang::XSingleComponentFactory
> xFactory
;
724 uno::Reference
< task::XJob
> xJob( xFactory
->createInstanceWithContext( xContext
), uno::UNO_QUERY_THROW
);
725 uno::Sequence
< beans::NamedValue
> aArgsForJob(1);
726 ScViewData
* pViewData
= GetViewData();
727 SfxViewShell
* pViewShell
= ( pViewData
? pViewData
->GetViewShell() : NULL
);
728 SfxViewFrame
* pViewFrame
= ( pViewShell
? pViewShell
->GetViewFrame() : NULL
);
729 SfxFrame
* pFrame
= ( pViewFrame
? &pViewFrame
->GetFrame() : NULL
);
730 uno::Reference
< frame::XController
> xController
= ( pFrame
? pFrame
->GetController() : 0 );
731 uno::Reference
< sheet::XSpreadsheetView
> xSpreadsheetView( xController
, uno::UNO_QUERY_THROW
);
732 aArgsForJob
[0] = beans::NamedValue( OUString( "SpreadsheetView" ),
733 uno::makeAny( xSpreadsheetView
) );
734 xJob
->execute( aArgsForJob
);
739 catch ( uno::Exception
& )
744 case SFX_EVENT_SAVEDOC
:
746 #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
747 if ( IsDocShared() && !SC_MOD()->IsInSharedDocSaving() )
749 bool bSuccess
= false;
754 uno::Reference
< frame::XModel
> xModel
;
758 xModel
.set( LoadSharedDocument(), uno::UNO_QUERY_THROW
);
759 uno::Reference
< util::XCloseable
> xCloseable( xModel
, uno::UNO_QUERY_THROW
);
761 // check if shared flag is set in shared file
762 bool bShared
= false;
763 ScModelObj
* pDocObj
= ScModelObj::getImplementation( xModel
);
764 ScDocShell
* pSharedDocShell
= ( pDocObj
? dynamic_cast< ScDocShell
* >( pDocObj
->GetObjectShell() ) : NULL
);
765 if ( pSharedDocShell
)
767 bShared
= pSharedDocShell
->HasSharedXMLFlagSet();
770 // #i87870# check if shared status was disabled and enabled again
771 bool bOwnEntry
= false;
772 bool bEntriesNotAccessible
= false;
775 ::svt::ShareControlFile
aControlFile( GetSharedFileURL() );
776 bOwnEntry
= aControlFile
.HasOwnEntry();
778 catch ( uno::Exception
& )
780 bEntriesNotAccessible
= true;
783 if ( bShared
&& bOwnEntry
)
785 uno::Reference
< frame::XStorable
> xStorable( xModel
, uno::UNO_QUERY_THROW
);
787 if ( xStorable
->isReadonly() )
789 xCloseable
->close( sal_True
);
791 OUString
aUserName( ScGlobal::GetRscString( STR_UNKNOWN_USER
) );
792 bool bNoLockAccess
= false;
795 ::svt::DocumentLockFile
aLockFile( GetSharedFileURL() );
796 uno::Sequence
< OUString
> aData
= aLockFile
.GetLockData();
797 if ( aData
.getLength() > LOCKFILE_SYSUSERNAME_ID
)
799 if ( !aData
[LOCKFILE_OOOUSERNAME_ID
].isEmpty() )
801 aUserName
= aData
[LOCKFILE_OOOUSERNAME_ID
];
803 else if ( !aData
[LOCKFILE_SYSUSERNAME_ID
].isEmpty() )
805 aUserName
= aData
[LOCKFILE_SYSUSERNAME_ID
];
809 catch ( uno::Exception
& )
811 bNoLockAccess
= true;
816 // TODO/LATER: in future an error regarding impossibility to open file for writing could be shown
817 ErrorHandler::HandleError( ERRCODE_IO_GENERAL
);
821 OUString
aMessage( ScGlobal::GetRscString( STR_FILE_LOCKED_SAVE_LATER
) );
822 aMessage
= aMessage
.replaceFirst( "%1", aUserName
);
824 WarningBox
aBox( GetActiveDialogParent(), WinBits( WB_RETRY_CANCEL
| WB_DEF_RETRY
), aMessage
);
825 if ( aBox
.Execute() == RET_RETRY
)
833 // merge changes from shared file into temp file
834 bool bSaveToShared
= false;
835 if ( pSharedDocShell
)
837 bSaveToShared
= MergeSharedDocument( pSharedDocShell
);
841 xCloseable
->close( sal_True
);
843 // TODO: keep file lock on shared file
845 // store to shared file
848 bool bChangedViewSettings
= false;
849 ScChangeViewSettings
* pChangeViewSet
= aDocument
.GetChangeViewSettings();
850 if ( pChangeViewSet
&& pChangeViewSet
->ShowChanges() )
852 pChangeViewSet
->SetShowChanges( false );
853 pChangeViewSet
->SetShowAccepted( false );
854 aDocument
.SetChangeViewSettings( *pChangeViewSet
);
855 bChangedViewSettings
= true;
858 uno::Reference
< frame::XStorable
> xStor( GetModel(), uno::UNO_QUERY_THROW
);
859 // TODO/LATER: More entries from the MediaDescriptor might be interesting for the merge
860 uno::Sequence
< beans::PropertyValue
> aValues(1);
861 aValues
[0].Name
= "FilterName";
862 aValues
[0].Value
<<= OUString( GetMedium()->GetFilter()->GetFilterName() );
864 SFX_ITEMSET_ARG( GetMedium()->GetItemSet(), pPasswordItem
, SfxStringItem
, SID_PASSWORD
, false);
865 if ( pPasswordItem
&& !pPasswordItem
->GetValue().isEmpty() )
867 aValues
.realloc( 2 );
868 aValues
[1].Name
= "Password";
869 aValues
[1].Value
<<= pPasswordItem
->GetValue();
872 SC_MOD()->SetInSharedDocSaving( true );
873 xStor
->storeToURL( GetSharedFileURL(), aValues
);
874 SC_MOD()->SetInSharedDocSaving( false );
876 if ( bChangedViewSettings
)
878 pChangeViewSet
->SetShowChanges( true );
879 pChangeViewSet
->SetShowAccepted( true );
880 aDocument
.SetChangeViewSettings( *pChangeViewSet
);
885 GetUndoManager()->Clear();
890 xCloseable
->close( sal_True
);
892 if ( bEntriesNotAccessible
)
894 // TODO/LATER: in future an error regarding impossibility to write to share control file could be shown
895 ErrorHandler::HandleError( ERRCODE_IO_GENERAL
);
899 WarningBox
aBox( GetActiveDialogParent(), WinBits( WB_OK
),
900 ScGlobal::GetRscString( STR_DOC_NOLONGERSHARED
) );
903 SfxBindings
* pBindings
= GetViewBindings();
906 pBindings
->ExecuteSynchron( SID_SAVEASDOC
);
911 catch ( uno::Exception
& )
913 OSL_FAIL( "SFX_EVENT_SAVEDOC: caught exception\n" );
914 SC_MOD()->SetInSharedDocSaving( false );
918 uno::Reference
< util::XCloseable
> xClose( xModel
, uno::UNO_QUERY_THROW
);
919 xClose
->close( sal_True
);
921 catch ( uno::Exception
& )
928 SetError( ERRCODE_IO_ABORT
, OUString( OSL_LOG_PREFIX
) ); // this error code will produce no error message, but will break the further saving process
933 pSheetSaveData
->SetInSupportedSave(true);
936 case SFX_EVENT_SAVEASDOC
:
938 if ( GetDocument()->GetExternalRefManager()->containsUnsavedReferences() )
940 WarningBox
aBox( GetActiveDialogParent(), WinBits( WB_YES_NO
),
941 ScGlobal::GetRscString( STR_UNSAVED_EXT_REF
) );
943 if( RET_NO
== aBox
.Execute())
945 SetError( ERRCODE_IO_ABORT
, OUString( OSL_LOG_PREFIX
) ); // this error code will produce no error message, but will break the further saving process
949 case SFX_EVENT_SAVETODOC
:
950 // #i108978# If no event is sent before saving, there will also be no "...DONE" event,
951 // and SAVE/SAVEAS can't be distinguished from SAVETO. So stream copying is only enabled
952 // if there is a SAVE/SAVEAS/SAVETO event first.
954 pSheetSaveData
->SetInSupportedSave(true);
956 case SFX_EVENT_SAVEDOCDONE
:
957 case SFX_EVENT_SAVEASDOCDONE
:
959 // new positions are used after "save" and "save as", but not "save to"
960 UseSheetSaveEntries(); // use positions from saved file for next saving
962 case SFX_EVENT_SAVETODOCDONE
:
963 // only reset the flag, don't use the new positions
965 pSheetSaveData
->SetInSupportedSave(false);
975 // Load contents for organizer
976 bool ScDocShell::LoadFrom( SfxMedium
& rMedium
)
978 LoadMediumGuard
aLoadGuard(&aDocument
);
979 ScRefreshTimerProtector
aProt( aDocument
.GetRefreshTimerControlAddress() );
981 WaitObject
aWait( GetActiveDialogParent() );
987 SFX_ITEMSET_ARG( rMedium
.GetItemSet(), pUpdateDocItem
, SfxUInt16Item
, SID_UPDATEDOCMODE
, false);
988 nCanUpdate
= pUpdateDocItem
? pUpdateDocItem
->GetValue() : com::sun::star::document::UpdateDocMode::NO_UPDATE
;
991 // until loading/saving only the styles in XML is implemented,
992 // load the whole file
993 bRet
= LoadXML( &rMedium
, NULL
);
996 SfxObjectShell::LoadFrom( rMedium
);
1001 static void lcl_parseHtmlFilterOption(const OUString
& rOption
, LanguageType
& rLang
, bool& rDateConvert
)
1003 OUStringBuffer aBuf
;
1004 std::vector
< OUString
> aTokens
;
1005 sal_Int32 n
= rOption
.getLength();
1006 const sal_Unicode
* p
= rOption
.getStr();
1007 for (sal_Int32 i
= 0; i
< n
; ++i
)
1009 const sal_Unicode c
= p
[i
];
1012 if (!aBuf
.isEmpty())
1013 aTokens
.push_back( aBuf
.makeStringAndClear() );
1019 if (!aBuf
.isEmpty())
1020 aTokens
.push_back( aBuf
.makeStringAndClear() );
1022 rLang
= LanguageType( 0 );
1023 rDateConvert
= false;
1025 if (aTokens
.size() > 0)
1026 rLang
= static_cast<LanguageType
>(aTokens
[0].toInt32());
1027 if (aTokens
.size() > 1)
1028 rDateConvert
= static_cast<bool>(aTokens
[1].toInt32());
1031 bool ScDocShell::ConvertFrom( SfxMedium
& rMedium
)
1033 LoadMediumGuard
aLoadGuard(&aDocument
);
1035 bool bRet
= false; // sal_False means user quit!
1036 // On error: Set error at stream
1038 ScRefreshTimerProtector
aProt( aDocument
.GetRefreshTimerControlAddress() );
1040 GetUndoManager()->Clear();
1042 // Set optimal col width after import?
1043 bool bSetColWidths
= false;
1044 bool bSetSimpleTextColWidths
= false;
1045 ScColWidthParam aColWidthParam
[MAXCOLCOUNT
];
1046 ScRange aColWidthRange
;
1047 // Set optimal row height after import?
1048 bool bSetRowHeights
= false;
1050 vector
<ScDocRowHeightUpdater::TabRanges
> aRecalcRowRangesArray
;
1052 // All filters need the complete file in one piece (not asynchronously)
1053 // So make sure that we transfer the whole file with CreateFileStream
1054 rMedium
.GetPhysicalName(); //! Call CreateFileStream directly, if available
1056 SFX_ITEMSET_ARG( rMedium
.GetItemSet(), pUpdateDocItem
, SfxUInt16Item
, SID_UPDATEDOCMODE
, false);
1057 nCanUpdate
= pUpdateDocItem
? pUpdateDocItem
->GetValue() : com::sun::star::document::UpdateDocMode::NO_UPDATE
;
1059 const SfxFilter
* pFilter
= rMedium
.GetFilter();
1062 OUString aFltName
= pFilter
->GetFilterName();
1064 bool bCalc3
= ( aFltName
.equalsAscii(pFilterSc30
) );
1065 bool bCalc4
= ( aFltName
.equalsAscii(pFilterSc40
) );
1066 if (!bCalc3
&& !bCalc4
)
1067 aDocument
.SetInsertingFromOtherDoc( true );
1069 if (aFltName
.equalsAscii(pFilterXML
))
1070 bRet
= LoadXML( &rMedium
, NULL
);
1071 else if (aFltName
.equalsAscii(pFilterSc10
))
1073 SvStream
* pStream
= rMedium
.GetInStream();
1076 FltError eError
= ScFormatFilter::Get().ScImportStarCalc10( *pStream
, &aDocument
);
1077 if (eError
!= eERR_OK
)
1080 SetError(eError
, OUString( OSL_LOG_PREFIX
));
1086 else if (aFltName
.equalsAscii(pFilterLotus
))
1089 SfxItemSet
* pSet
= rMedium
.GetItemSet();
1090 const SfxPoolItem
* pItem
;
1091 if ( pSet
&& SFX_ITEM_SET
==
1092 pSet
->GetItemState( SID_FILE_FILTEROPTIONS
, true, &pItem
) )
1094 sItStr
= ((const SfxStringItem
*)pItem
)->GetValue();
1097 if (sItStr
.isEmpty())
1099 // default for lotus import (from API without options):
1101 sItStr
= ScGlobal::GetCharsetString( RTL_TEXTENCODING_IBM_437
);
1104 FltError eError
= ScFormatFilter::Get().ScImportLotus123( rMedium
, &aDocument
,
1105 ScGlobal::GetCharsetValue(sItStr
));
1106 if (eError
!= eERR_OK
)
1109 SetError(eError
, OUString( OSL_LOG_PREFIX
));
1111 if( ( eError
& ERRCODE_WARNING_MASK
) == ERRCODE_WARNING_MASK
)
1116 bSetColWidths
= true;
1117 bSetRowHeights
= true;
1119 else if ( aFltName
.equalsAscii(pFilterExcel4
) || aFltName
.equalsAscii(pFilterExcel5
) ||
1120 aFltName
.equalsAscii(pFilterExcel95
) || aFltName
.equalsAscii(pFilterExcel97
) ||
1121 aFltName
.equalsAscii(pFilterEx4Temp
) || aFltName
.equalsAscii(pFilterEx5Temp
) ||
1122 aFltName
.equalsAscii(pFilterEx95Temp
) || aFltName
.equalsAscii(pFilterEx97Temp
) )
1124 EXCIMPFORMAT eFormat
= EIF_AUTO
;
1125 if ( aFltName
.equalsAscii(pFilterExcel4
) || aFltName
.equalsAscii(pFilterEx4Temp
) )
1126 eFormat
= EIF_BIFF_LE4
;
1127 else if ( aFltName
.equalsAscii(pFilterExcel5
) || aFltName
.equalsAscii(pFilterExcel95
) ||
1128 aFltName
.equalsAscii(pFilterEx5Temp
) || aFltName
.equalsAscii(pFilterEx95Temp
) )
1129 eFormat
= EIF_BIFF5
;
1130 else if ( aFltName
.equalsAscii(pFilterExcel97
) || aFltName
.equalsAscii(pFilterEx97Temp
) )
1131 eFormat
= EIF_BIFF8
;
1133 MakeDrawLayer(); //! In the filter
1134 CalcOutputFactor(); // prepare update of row height
1135 FltError eError
= ScFormatFilter::Get().ScImportExcel( rMedium
, &aDocument
, eFormat
);
1136 aDocument
.UpdateFontCharSet();
1137 if ( aDocument
.IsChartListenerCollectionNeedsUpdate() )
1138 aDocument
.UpdateChartListenerCollection(); //! For all imports?
1140 // all graphics objects must have names
1141 aDocument
.EnsureGraphicNames();
1143 if (eError
== SCWARN_IMPORT_RANGE_OVERFLOW
)
1146 SetError(eError
, OUString( OSL_LOG_PREFIX
));
1149 else if (eError
!= eERR_OK
)
1152 SetError(eError
, OUString( OSL_LOG_PREFIX
));
1157 else if (aFltName
.equalsAscii(pFilterAscii
))
1159 SfxItemSet
* pSet
= rMedium
.GetItemSet();
1160 const SfxPoolItem
* pItem
;
1161 ScAsciiOptions aOptions
;
1162 bool bOptInit
= false;
1164 if ( pSet
&& SFX_ITEM_SET
==
1165 pSet
->GetItemState( SID_FILE_FILTEROPTIONS
, true, &pItem
) )
1167 aOptions
.ReadFromString( ((const SfxStringItem
*)pItem
)->GetValue() );
1173 // default for ascii import (from API without options):
1174 // ISO8859-1/MS_1252 encoding, comma, double quotes
1176 aOptions
.SetCharSet( RTL_TEXTENCODING_MS_1252
);
1177 aOptions
.SetFieldSeps( OUString(',') );
1178 aOptions
.SetTextSep( '"' );
1181 FltError eError
= eERR_OK
;
1182 bool bOverflowRow
, bOverflowCol
, bOverflowCell
;
1183 bOverflowRow
= bOverflowCol
= bOverflowCell
= false;
1185 if( ! rMedium
.IsStorage() )
1187 ScImportExport
aImpEx( &aDocument
);
1188 aImpEx
.SetExtOptions( aOptions
);
1190 SvStream
* pInStream
= rMedium
.GetInStream();
1193 pInStream
->SetStreamCharSet( aOptions
.GetCharSet() );
1194 pInStream
->Seek( 0 );
1195 bRet
= aImpEx
.ImportStream( *pInStream
, rMedium
.GetBaseURL() );
1196 eError
= bRet
? eERR_OK
: SCERR_IMPORT_CONNECT
;
1197 aDocument
.StartAllListeners();
1198 sc::SetFormulaDirtyContext aCxt
;
1199 aDocument
.SetAllFormulasDirty(aCxt
);
1200 INetURLObject
aURLObjForDefaultNameSheetName(rMedium
.GetName());
1201 aDocument
.RenameTab(0,aURLObjForDefaultNameSheetName
.GetBase());
1202 bOverflowRow
= aImpEx
.IsOverflowRow();
1203 bOverflowCol
= aImpEx
.IsOverflowCol();
1204 bOverflowCell
= aImpEx
.IsOverflowCell();
1208 OSL_FAIL( "No Stream" );
1212 if (eError
!= eERR_OK
)
1215 SetError(eError
, OUString( OSL_LOG_PREFIX
));
1217 else if (!GetError() && (bOverflowRow
|| bOverflowCol
|| bOverflowCell
))
1219 // precedence: row, column, cell
1220 FltError nWarn
= (bOverflowRow
? SCWARN_IMPORT_ROW_OVERFLOW
:
1221 (bOverflowCol
? SCWARN_IMPORT_COLUMN_OVERFLOW
:
1222 SCWARN_IMPORT_CELL_OVERFLOW
));
1223 SetError( nWarn
, OUString( OSL_LOG_PREFIX
));
1225 bSetColWidths
= true;
1226 bSetSimpleTextColWidths
= true;
1228 else if (aFltName
.equalsAscii(pFilterDBase
))
1231 SfxItemSet
* pSet
= rMedium
.GetItemSet();
1232 const SfxPoolItem
* pItem
;
1233 if ( pSet
&& SFX_ITEM_SET
==
1234 pSet
->GetItemState( SID_FILE_FILTEROPTIONS
, true, &pItem
) )
1236 sItStr
= ((const SfxStringItem
*)pItem
)->GetValue();
1239 if (sItStr
.isEmpty())
1241 // default for dBase import (from API without options):
1244 sItStr
= ScGlobal::GetCharsetString( RTL_TEXTENCODING_IBM_850
);
1247 ScDocRowHeightUpdater::TabRanges
aRecalcRanges(0);
1248 sal_uLong eError
= DBaseImport( rMedium
.GetPhysicalName(),
1249 ScGlobal::GetCharsetValue(sItStr
), aColWidthParam
, *aRecalcRanges
.mpRanges
);
1250 aRecalcRowRangesArray
.push_back(aRecalcRanges
);
1252 if (eError
!= eERR_OK
)
1255 SetError(eError
, OUString( OSL_LOG_PREFIX
));
1256 bRet
= ( eError
== SCWARN_IMPORT_RANGE_OVERFLOW
);
1261 aColWidthRange
.aStart
.SetRow( 1 ); // Except for the column header
1262 bSetColWidths
= true;
1263 bSetSimpleTextColWidths
= true;
1265 else if (aFltName
.equalsAscii(pFilterDif
))
1267 SvStream
* pStream
= rMedium
.GetInStream();
1272 SfxItemSet
* pSet
= rMedium
.GetItemSet();
1273 const SfxPoolItem
* pItem
;
1274 if ( pSet
&& SFX_ITEM_SET
==
1275 pSet
->GetItemState( SID_FILE_FILTEROPTIONS
, true, &pItem
) )
1277 sItStr
= ((const SfxStringItem
*)pItem
)->GetValue();
1280 if (sItStr
.isEmpty())
1282 // default for DIF import (from API without options):
1283 // ISO8859-1/MS_1252 encoding
1285 sItStr
= ScGlobal::GetCharsetString( RTL_TEXTENCODING_MS_1252
);
1288 eError
= ScFormatFilter::Get().ScImportDif( *pStream
, &aDocument
, ScAddress(0,0,0),
1289 ScGlobal::GetCharsetValue(sItStr
));
1290 if (eError
!= eERR_OK
)
1293 SetError(eError
, OUString( OSL_LOG_PREFIX
));
1295 if( ( eError
& ERRCODE_WARNING_MASK
) == ERRCODE_WARNING_MASK
)
1301 bSetColWidths
= true;
1302 bSetSimpleTextColWidths
= true;
1303 bSetRowHeights
= true;
1305 else if (aFltName
.equalsAscii(pFilterSylk
))
1307 FltError eError
= SCERR_IMPORT_UNKNOWN
;
1308 if( !rMedium
.IsStorage() )
1310 ScImportExport
aImpEx( &aDocument
);
1312 SvStream
* pInStream
= rMedium
.GetInStream();
1315 pInStream
->Seek( 0 );
1316 bRet
= aImpEx
.ImportStream( *pInStream
, rMedium
.GetBaseURL(), SOT_FORMATSTR_ID_SYLK
);
1317 eError
= bRet
? eERR_OK
: SCERR_IMPORT_UNKNOWN
;
1318 aDocument
.StartAllListeners();
1319 sc::SetFormulaDirtyContext aCxt
;
1320 aDocument
.SetAllFormulasDirty(aCxt
);
1324 OSL_FAIL( "No Stream" );
1328 if ( eError
!= eERR_OK
&& !GetError() )
1329 SetError(eError
, OUString( OSL_LOG_PREFIX
));
1330 bSetColWidths
= true;
1331 bSetSimpleTextColWidths
= true;
1332 bSetRowHeights
= true;
1334 else if (aFltName
.equalsAscii(pFilterQPro6
))
1336 FltError eError
= ScFormatFilter::Get().ScImportQuattroPro( rMedium
, &aDocument
);
1337 if (eError
!= eERR_OK
)
1340 SetError( eError
, OUString( OSL_LOG_PREFIX
) );
1341 if( ( eError
& ERRCODE_WARNING_MASK
) == ERRCODE_WARNING_MASK
)
1346 // TODO: Filter should set column widths. Not doing it here, it may
1347 // result in very narrow or wide columns, depending on content.
1348 // Setting row heights makes cells with font size attribution or
1349 // wrapping enabled look nicer..
1350 bSetRowHeights
= true;
1352 else if (aFltName
.equalsAscii(pFilterRtf
))
1354 FltError eError
= SCERR_IMPORT_UNKNOWN
;
1355 if( !rMedium
.IsStorage() )
1357 SvStream
* pInStream
= rMedium
.GetInStream();
1360 pInStream
->Seek( 0 );
1362 eError
= ScFormatFilter::Get().ScImportRTF( *pInStream
, rMedium
.GetBaseURL(), &aDocument
, aRange
);
1363 if (eError
!= eERR_OK
)
1366 SetError(eError
, OUString( OSL_LOG_PREFIX
));
1368 if( ( eError
& ERRCODE_WARNING_MASK
) == ERRCODE_WARNING_MASK
)
1373 aDocument
.StartAllListeners();
1374 sc::SetFormulaDirtyContext aCxt
;
1375 aDocument
.SetAllFormulasDirty(aCxt
);
1376 bSetColWidths
= true;
1377 bSetRowHeights
= true;
1381 OSL_FAIL( "No Stream" );
1385 if ( eError
!= eERR_OK
&& !GetError() )
1386 SetError(eError
, OUString( OSL_LOG_PREFIX
));
1388 else if (aFltName
.equalsAscii(pFilterHtml
) || aFltName
.equalsAscii(pFilterHtmlWebQ
))
1390 FltError eError
= SCERR_IMPORT_UNKNOWN
;
1391 bool bWebQuery
= aFltName
.equalsAscii(pFilterHtmlWebQ
);
1392 if( !rMedium
.IsStorage() )
1394 SvStream
* pInStream
= rMedium
.GetInStream();
1397 LanguageType eLang
= LANGUAGE_SYSTEM
;
1398 bool bDateConvert
= false;
1399 SfxItemSet
* pSet
= rMedium
.GetItemSet();
1400 const SfxPoolItem
* pItem
;
1401 if ( pSet
&& SFX_ITEM_SET
==
1402 pSet
->GetItemState( SID_FILE_FILTEROPTIONS
, true, &pItem
) )
1404 OUString aFilterOption
= (static_cast<const SfxStringItem
*>(pItem
))->GetValue();
1405 lcl_parseHtmlFilterOption(aFilterOption
, eLang
, bDateConvert
);
1408 pInStream
->Seek( 0 );
1410 // HTML does its own ColWidth/RowHeight
1412 SvNumberFormatter
aNumFormatter( comphelper::getProcessComponentContext(), eLang
);
1413 eError
= ScFormatFilter::Get().ScImportHTML( *pInStream
, rMedium
.GetBaseURL(), &aDocument
, aRange
,
1414 GetOutputFactor(), !bWebQuery
, &aNumFormatter
, bDateConvert
);
1415 if (eError
!= eERR_OK
)
1418 SetError(eError
, OUString( OSL_LOG_PREFIX
));
1420 if( ( eError
& ERRCODE_WARNING_MASK
) == ERRCODE_WARNING_MASK
)
1425 aDocument
.StartAllListeners();
1427 sc::SetFormulaDirtyContext aCxt
;
1428 aDocument
.SetAllFormulasDirty(aCxt
);
1432 OSL_FAIL( "No Stream" );
1436 if ( eError
!= eERR_OK
&& !GetError() )
1437 SetError(eError
, OUString( OSL_LOG_PREFIX
));
1442 SetError(SCERR_IMPORT_NI
, OUString( OSL_LOG_PREFIX
));
1446 aDocument
.SetInsertingFromOtherDoc( false );
1450 OSL_FAIL("No Filter in ConvertFrom");
1455 if ( bRet
&& (bSetColWidths
|| bSetRowHeights
) )
1456 { // Adjust column width/row height; base 100% zoom
1457 Fraction
aZoom( 1, 1 );
1458 double nPPTX
= ScGlobal::nScreenPPTX
* (double) aZoom
/ GetOutputFactor(); // Factor is printer display ratio
1459 double nPPTY
= ScGlobal::nScreenPPTY
* (double) aZoom
;
1460 VirtualDevice aVirtDev
;
1461 // all sheets (for Excel import)
1462 SCTAB nTabCount
= aDocument
.GetTableCount();
1463 for (SCTAB nTab
=0; nTab
<nTabCount
; nTab
++)
1467 aDocument
.GetCellArea( nTab
, nEndCol
, nEndRow
);
1468 aColWidthRange
.aEnd
.SetCol( nEndCol
);
1469 aColWidthRange
.aEnd
.SetRow( nEndRow
);
1471 aMark
.SetMarkArea( aColWidthRange
);
1472 aMark
.MarkToMulti();
1474 // Order is important: First width, then height
1475 if ( bSetColWidths
)
1477 for ( SCCOL nCol
=0; nCol
<= nEndCol
; nCol
++ )
1479 if (!bSetSimpleTextColWidths
)
1480 aColWidthParam
[nCol
].mbSimpleText
= false;
1482 sal_uInt16 nWidth
= aDocument
.GetOptimalColWidth(
1483 nCol
, nTab
, &aVirtDev
, nPPTX
, nPPTY
, aZoom
, aZoom
, false, &aMark
,
1484 &aColWidthParam
[nCol
] );
1485 aDocument
.SetColWidth( nCol
, nTab
,
1486 nWidth
+ (sal_uInt16
)ScGlobal::nLastColWidthExtra
);
1493 // Update all rows in all tables.
1494 ScSizeDeviceProvider
aProv(this);
1495 ScDocRowHeightUpdater
aUpdater(aDocument
, aProv
.GetDevice(), aProv
.GetPPTX(), aProv
.GetPPTY(), NULL
);
1498 else if (!aRecalcRowRangesArray
.empty())
1500 // Update only specified row ranges for better performance.
1501 ScSizeDeviceProvider
aProv(this);
1502 ScDocRowHeightUpdater
aUpdater(aDocument
, aProv
.GetDevice(), aProv
.GetPPTX(), aProv
.GetPPTY(), &aRecalcRowRangesArray
);
1506 FinishedLoading( SFX_LOADED_MAINDOCUMENT
| SFX_LOADED_IMAGES
);
1509 // invalidate eventually temporary table areas
1511 aDocument
.InvalidateTableArea();
1518 bool ScDocShell::LoadExternal( SfxMedium
& rMed
)
1520 const SfxFilter
* pFilter
= rMed
.GetFilter();
1524 if (pFilter
->GetProviderName() == "orcus")
1526 ScOrcusFilters
* pOrcus
= ScFormatFilter::Get().GetOrcusFilters();
1530 const OUString
& rFilterName
= pFilter
->GetName();
1531 if (rFilterName
== "gnumeric")
1533 if (!pOrcus
->importGnumeric(aDocument
, rMed
))
1536 else if (rFilterName
== "csv")
1538 if (!pOrcus
->importCSV(aDocument
, rMed
))
1541 else if (rFilterName
== "xlsx")
1543 if (!pOrcus
->importXLSX(aDocument
, rMed
))
1546 else if (rFilterName
== "ods")
1548 if (!pOrcus
->importODS(aDocument
, rMed
))
1552 FinishedLoading(SFX_LOADED_MAINDOCUMENT
| SFX_LOADED_IMAGES
);
1560 ScDocShell::PrepareSaveGuard::PrepareSaveGuard( ScDocShell
& rDocShell
)
1561 : mrDocShell( rDocShell
)
1563 // DoEnterHandler not here (because of AutoSave), is in ExecuteSave.
1565 ScChartListenerCollection
* pCharts
= mrDocShell
.aDocument
.GetChartListenerCollection();
1567 pCharts
->UpdateDirtyCharts(); // Charts to be updated.
1568 mrDocShell
.aDocument
.StopTemporaryChartLock();
1569 if (mrDocShell
.pAutoStyleList
)
1570 mrDocShell
.pAutoStyleList
->ExecuteAllNow(); // Execute template timeouts now.
1571 if (mrDocShell
.aDocument
.HasExternalRefManager())
1573 ScExternalRefManager
* pRefMgr
= mrDocShell
.aDocument
.GetExternalRefManager();
1574 if (pRefMgr
&& pRefMgr
->hasExternalData())
1576 pRefMgr
->setAllCacheTableReferencedStati( false);
1577 mrDocShell
.aDocument
.MarkUsedExternalReferences(); // Mark tables of external references to be written.
1580 if (mrDocShell
.GetCreateMode()== SFX_CREATE_MODE_STANDARD
)
1581 mrDocShell
.SfxObjectShell::SetVisArea( Rectangle() ); // "Normally" worked on => no VisArea.
1584 ScDocShell::PrepareSaveGuard::~PrepareSaveGuard()
1586 if (mrDocShell
.aDocument
.HasExternalRefManager())
1588 ScExternalRefManager
* pRefMgr
= mrDocShell
.aDocument
.GetExternalRefManager();
1589 if (pRefMgr
&& pRefMgr
->hasExternalData())
1591 // Prevent accidental data loss due to lack of knowledge.
1592 pRefMgr
->setAllCacheTableReferencedStati( true);
1598 bool ScDocShell::Save()
1600 ScRefreshTimerProtector
aProt( aDocument
.GetRefreshTimerControlAddress() );
1602 PrepareSaveGuard
aPrepareGuard( *this);
1604 SfxViewFrame
* pFrame1
= SfxViewFrame::GetFirst( this );
1607 Window
* pWindow
= &pFrame1
->GetWindow();
1610 Window
* pSysWin
= pWindow
->GetSystemWindow();
1613 pSysWin
->SetAccessibleName(OUString());
1617 // wait cursor is handled with progress bar
1618 bool bRet
= SfxObjectShell::Save();
1620 bRet
= SaveXML( GetMedium(), NULL
);
1627 * Remove the file name from the full path, to keep only the directory path.
1629 void popFileName(OUString
& rPath
)
1631 if (!rPath
.isEmpty())
1633 INetURLObject
aURLObj(rPath
);
1634 aURLObj
.removeSegment();
1635 rPath
= aURLObj
.GetMainURL(INetURLObject::NO_DECODE
);
1641 bool ScDocShell::SaveAs( SfxMedium
& rMedium
)
1643 OUString aCurPath
; // empty for new document that hasn't been saved.
1644 const SfxMedium
* pCurMedium
= GetMedium();
1647 aCurPath
= pCurMedium
->GetName();
1648 popFileName(aCurPath
);
1651 if (!aCurPath
.isEmpty())
1653 // current document has a path -> not a brand-new document.
1654 OUString aNewPath
= rMedium
.GetName();
1655 popFileName(aNewPath
);
1656 OUString aRel
= URIHelper::simpleNormalizedMakeRelative(aCurPath
, aNewPath
);
1657 if (!aRel
.isEmpty())
1659 // Directory path will change before and after the save.
1660 aDocument
.InvalidateStreamOnSave();
1664 ScTabViewShell
* pViewShell
= GetBestViewShell();
1665 bool bNeedsRehash
= ScPassHashHelper::needsPassHashRegen(aDocument
, PASSHASH_SHA1
);
1667 // legacy xls hash double-hashed by SHA1 is also supported.
1668 bNeedsRehash
= ScPassHashHelper::needsPassHashRegen(aDocument
, PASSHASH_XL
, PASSHASH_SHA1
);
1670 if (pViewShell
&& bNeedsRehash
)
1672 if (!pViewShell
->ExecuteRetypePassDlg(PASSHASH_SHA1
))
1673 // password re-type cancelled. Don't save the document.
1678 ScRefreshTimerProtector
aProt( aDocument
.GetRefreshTimerControlAddress() );
1680 PrepareSaveGuard
aPrepareGuard( *this);
1682 OUString aFltName
= rMedium
.GetFilter()->GetFilterName();
1683 bool bChartExport
= aFltName
.indexOf("chart8") != -1;
1685 // wait cursor is handled with progress bar
1689 bRet
= SfxObjectShell::SaveAs( rMedium
);
1691 bRet
= SaveXML( &rMedium
, NULL
);
1695 bRet
= SaveCurrentChart( rMedium
);
1702 bool ScDocShell::IsInformationLost()
1704 //FIXME: If we have time build a correct own way how to handle this
1705 return SfxObjectShell::IsInformationLost();
1710 // Xcl-like column width measured in characters of standard font.
1711 sal_Int32
lcl_ScDocShell_GetColWidthInChars( sal_uInt16 nWidth
)
1719 return sal_Int32( f
);
1723 void lcl_ScDocShell_GetFixedWidthString( OUString
& rStr
, const ScDocument
& rDoc
,
1724 SCTAB nTab
, SCCOL nCol
, bool bValue
, SvxCellHorJustify eHorJust
)
1726 OUString aString
= rStr
;
1727 sal_Int32 nLen
= lcl_ScDocShell_GetColWidthInChars(
1728 rDoc
.GetColWidth( nCol
, nTab
) );
1729 //If the text won't fit in the column
1730 if ( nLen
< aString
.getLength() )
1732 OUStringBuffer aReplacement
;
1734 aReplacement
.append("###");
1736 aReplacement
.append(aString
);
1737 //truncate to the number of characters that should fit, even in the
1738 //bValue case nLen might be < len ###
1739 aString
= comphelper::string::truncateToLength(aReplacement
, nLen
).makeStringAndClear();
1741 if ( nLen
> aString
.getLength() )
1743 if ( bValue
&& eHorJust
== SVX_HOR_JUSTIFY_STANDARD
)
1744 eHorJust
= SVX_HOR_JUSTIFY_RIGHT
;
1745 sal_Int32 nBlanks
= nLen
- aString
.getLength();
1748 case SVX_HOR_JUSTIFY_RIGHT
:
1750 OUStringBuffer aTmp
;
1751 aTmp
= comphelper::string::padToLength( aTmp
, nBlanks
, ' ' );
1752 aString
= aTmp
.append(aString
).makeStringAndClear();
1755 case SVX_HOR_JUSTIFY_CENTER
:
1757 sal_Int32 nLeftPad
= nBlanks
/ 2;
1758 OUStringBuffer aTmp
;
1759 comphelper::string::padToLength( aTmp
, nLeftPad
, ' ' );
1760 aTmp
.append(aString
);
1761 comphelper::string::padToLength( aTmp
, nLen
, ' ' );
1762 aString
= aTmp
.makeStringAndClear();
1767 OUStringBuffer
aTmp(aString
);
1768 comphelper::string::padToLength( aTmp
, nLen
, ' ' );
1769 aString
= aTmp
.makeStringAndClear();
1777 void lcl_ScDocShell_WriteEmptyFixedWidthString( SvStream
& rStream
,
1778 const ScDocument
& rDoc
, SCTAB nTab
, SCCOL nCol
)
1781 lcl_ScDocShell_GetFixedWidthString( aString
, rDoc
, nTab
, nCol
, false,
1782 SVX_HOR_JUSTIFY_STANDARD
);
1783 rStream
.WriteUnicodeOrByteText( aString
);
1786 template<typename StrT
, typename SepCharT
>
1787 sal_Int32
getTextSepPos(
1788 const StrT
& rStr
, const ScImportOptions
& rAsciiOpt
, const SepCharT
& rTextSep
, const SepCharT
& rFieldSep
, bool& rNeedQuotes
)
1790 // #i116636# quotes are needed if text delimiter (quote), field delimiter,
1791 // or LF is in the cell text.
1792 sal_Int32 nPos
= rStr
.indexOf(rTextSep
);
1793 rNeedQuotes
= rAsciiOpt
.bQuoteAllText
|| (nPos
>= 0) ||
1794 (rStr
.indexOf(rFieldSep
) >= 0) ||
1795 (rStr
.indexOf('\n') >= 0);
1799 template<typename StrT
, typename StrBufT
>
1800 void escapeTextSep(sal_Int32 nPos
, const StrT
& rStrDelim
, StrT
& rStr
)
1805 aBuf
.insert(nPos
, rStrDelim
);
1806 rStr
= aBuf
.makeStringAndClear();
1807 nPos
= rStr
.indexOf(rStrDelim
, nPos
+1+rStrDelim
.getLength());
1813 void ScDocShell::AsciiSave( SvStream
& rStream
, const ScImportOptions
& rAsciiOpt
)
1815 sal_Unicode cDelim
= rAsciiOpt
.nFieldSepCode
;
1816 sal_Unicode cStrDelim
= rAsciiOpt
.nTextSepCode
;
1817 rtl_TextEncoding eCharSet
= rAsciiOpt
.eCharSet
;
1818 bool bFixedWidth
= rAsciiOpt
.bFixedWidth
;
1819 bool bSaveAsShown
= rAsciiOpt
.bSaveAsShown
;
1820 bool bShowFormulas
= rAsciiOpt
.bSaveFormulas
;
1822 rtl_TextEncoding eOldCharSet
= rStream
.GetStreamCharSet();
1823 rStream
.SetStreamCharSet( eCharSet
);
1824 sal_uInt16 nOldNumberFormatInt
= rStream
.GetNumberFormatInt();
1825 OString aStrDelimEncoded
; // only used if not Unicode
1826 OUString aStrDelimDecoded
; // only used if context encoding
1827 OString aDelimEncoded
;
1828 OUString aDelimDecoded
;
1829 bool bContextOrNotAsciiEncoding
;
1830 if ( eCharSet
== RTL_TEXTENCODING_UNICODE
)
1832 rStream
.StartWritingUnicodeText();
1833 bContextOrNotAsciiEncoding
= false;
1837 aStrDelimEncoded
= OString(&cStrDelim
, 1, eCharSet
);
1838 aDelimEncoded
= OString(&cDelim
, 1, eCharSet
);
1839 rtl_TextEncodingInfo aInfo
;
1840 aInfo
.StructSize
= sizeof(aInfo
);
1841 if ( rtl_getTextEncodingInfo( eCharSet
, &aInfo
) )
1843 bContextOrNotAsciiEncoding
=
1844 (((aInfo
.Flags
& RTL_TEXTENCODING_INFO_CONTEXT
) != 0) ||
1845 ((aInfo
.Flags
& RTL_TEXTENCODING_INFO_ASCII
) == 0));
1846 if ( bContextOrNotAsciiEncoding
)
1848 aStrDelimDecoded
= OStringToOUString(aStrDelimEncoded
, eCharSet
);
1849 aDelimDecoded
= OStringToOUString(aDelimEncoded
, eCharSet
);
1853 bContextOrNotAsciiEncoding
= false;
1856 SCCOL nStartCol
= 0;
1857 SCROW nStartRow
= 0;
1858 SCTAB nTab
= GetSaveTab();
1861 aDocument
.GetCellArea( nTab
, nEndCol
, nEndRow
);
1863 ScProgress
aProgress( this, ScGlobal::GetRscString( STR_SAVE_DOC
), nEndRow
);
1867 bool bTabProtect
= aDocument
.IsTabProtected( nTab
);
1871 SCCOL nNextCol
= nStartCol
;
1872 SCROW nNextRow
= nStartRow
;
1875 SvNumberFormatter
& rFormatter
= *aDocument
.GetFormatTable();
1877 ScHorizontalCellIterator
aIter( &aDocument
, nTab
, nStartCol
, nStartRow
,
1879 ScRefCellValue
* pCell
;
1880 while ( ( pCell
= aIter
.GetNext( nCol
, nRow
) ) != NULL
)
1882 bool bProgress
= false; // only upon line change
1883 if ( nNextRow
< nRow
)
1884 { // empty rows or/and empty columns up to end of row
1886 for ( nEmptyCol
= nNextCol
; nEmptyCol
< nEndCol
; nEmptyCol
++ )
1887 { // remaining columns of last row
1889 lcl_ScDocShell_WriteEmptyFixedWidthString( rStream
,
1890 aDocument
, nTab
, nEmptyCol
);
1891 else if ( cDelim
!= 0 )
1892 rStream
.WriteUniOrByteChar( cDelim
);
1896 for ( nEmptyRow
= nNextRow
; nEmptyRow
< nRow
; nEmptyRow
++ )
1897 { // completely empty rows
1898 for ( nEmptyCol
= nStartCol
; nEmptyCol
< nEndCol
; nEmptyCol
++ )
1901 lcl_ScDocShell_WriteEmptyFixedWidthString( rStream
,
1902 aDocument
, nTab
, nEmptyCol
);
1903 else if ( cDelim
!= 0 )
1904 rStream
.WriteUniOrByteChar( cDelim
);
1908 for ( nEmptyCol
= nStartCol
; nEmptyCol
< nCol
; nEmptyCol
++ )
1909 { // empty columns at beginning of row
1911 lcl_ScDocShell_WriteEmptyFixedWidthString( rStream
,
1912 aDocument
, nTab
, nEmptyCol
);
1913 else if ( cDelim
!= 0 )
1914 rStream
.WriteUniOrByteChar( cDelim
);
1918 else if ( nNextCol
< nCol
)
1919 { // empty columns in same row
1920 for ( nEmptyCol
= nNextCol
; nEmptyCol
< nCol
; nEmptyCol
++ )
1921 { // columns in between
1923 lcl_ScDocShell_WriteEmptyFixedWidthString( rStream
,
1924 aDocument
, nTab
, nEmptyCol
);
1925 else if ( cDelim
!= 0 )
1926 rStream
.WriteUniOrByteChar( cDelim
);
1929 if ( nCol
== nEndCol
)
1932 nNextCol
= nStartCol
;
1933 nNextRow
= nRow
+ 1;
1936 nNextCol
= nCol
+ 1;
1938 CellType eType
= pCell
->meType
;
1939 ScAddress
aPos(nCol
, nRow
, nTab
);
1942 const ScProtectionAttr
* pProtAttr
=
1943 (const ScProtectionAttr
*) aDocument
.GetAttr(
1944 nCol
, nRow
, nTab
, ATTR_PROTECTION
);
1945 if ( pProtAttr
->GetHideCell() ||
1946 ( eType
== CELLTYPE_FORMULA
&& bShowFormulas
&&
1947 pProtAttr
->GetHideFormula() ) )
1948 eType
= CELLTYPE_NONE
; // hide
1957 case CELLTYPE_FORMULA
:
1959 sal_uInt16 nErrCode
;
1960 if ( bShowFormulas
)
1962 pCell
->mpFormula
->GetFormula(aString
);
1965 else if ((nErrCode
= pCell
->mpFormula
->GetErrCode()) != 0)
1967 aString
= ScGlobal::GetErrorString( nErrCode
);
1970 else if (pCell
->mpFormula
->IsValue())
1972 sal_uInt32 nFormat
= aDocument
.GetNumberFormat(aPos
);
1973 if ( bFixedWidth
|| bSaveAsShown
)
1976 aString
= ScCellFormat::GetString(aDocument
, aPos
, nFormat
, &pDummy
, rFormatter
);
1977 bString
= bSaveAsShown
&& rFormatter
.IsTextFormat( nFormat
);
1981 ScCellFormat::GetInputString(*pCell
, nFormat
, aString
, rFormatter
, &aDocument
);
1989 sal_uInt32 nFormat
= aDocument
.GetNumberFormat(aPos
);
1991 aString
= ScCellFormat::GetString(aDocument
, aPos
, nFormat
, &pDummy
, rFormatter
);
1994 aString
= pCell
->mpFormula
->GetString().getString();
1999 case CELLTYPE_STRING
:
2002 sal_uInt32 nFormat
= aDocument
.GetNumberFormat(aPos
);
2004 aString
= ScCellFormat::GetString(aDocument
, aPos
, nFormat
, &pDummy
, rFormatter
);
2007 aString
= pCell
->mpString
->getString();
2010 case CELLTYPE_EDIT
:
2012 const EditTextObject
* pObj
= pCell
->mpEditText
;
2013 EditEngine
& rEngine
= aDocument
.GetEditEngine();
2014 rEngine
.SetText( *pObj
);
2015 aString
= rEngine
.GetText(); // including LF
2019 case CELLTYPE_VALUE
:
2022 aDocument
.GetNumberFormat( nCol
, nRow
, nTab
, nFormat
);
2023 if ( bFixedWidth
|| bSaveAsShown
)
2026 aString
= ScCellFormat::GetString(aDocument
, aPos
, nFormat
, &pDummy
, rFormatter
);
2027 bString
= bSaveAsShown
&& rFormatter
.IsTextFormat( nFormat
);
2031 ScCellFormat::GetInputString(*pCell
, nFormat
, aString
, rFormatter
, &aDocument
);
2037 OSL_FAIL( "ScDocShell::AsciiSave: unknown CellType" );
2044 SvxCellHorJustify eHorJust
= (SvxCellHorJustify
)
2045 ((const SvxHorJustifyItem
*) aDocument
.GetAttr( nCol
, nRow
,
2046 nTab
, ATTR_HOR_JUSTIFY
))->GetValue();
2047 lcl_ScDocShell_GetFixedWidthString( aString
, aDocument
, nTab
, nCol
,
2048 !bString
, eHorJust
);
2049 rStream
.WriteUnicodeOrByteText( aString
);
2053 OUString aUniString
= aString
;// TODO: remove that later
2054 if (!bString
&& cStrDelim
!= 0 && !aUniString
.isEmpty())
2056 sal_Unicode c
= aUniString
[0];
2057 bString
= (c
== cStrDelim
|| c
== ' ' ||
2058 aUniString
.endsWith(" ") ||
2059 aUniString
.indexOf(cStrDelim
) >= 0);
2060 if (!bString
&& cDelim
!= 0)
2061 bString
= (aUniString
.indexOf(cDelim
) >= 0);
2065 if ( cStrDelim
!= 0 ) //@ BugId 55355
2067 if ( eCharSet
== RTL_TEXTENCODING_UNICODE
)
2069 bool bNeedQuotes
= false;
2070 sal_Int32 nPos
= getTextSepPos(
2071 aUniString
, rAsciiOpt
, cStrDelim
, cDelim
, bNeedQuotes
);
2073 escapeTextSep
<OUString
, OUStringBuffer
>(
2074 nPos
, OUString(cStrDelim
), aUniString
);
2077 rStream
.WriteUniOrByteChar( cStrDelim
, eCharSet
);
2078 write_uInt16s_FromOUString(rStream
, aUniString
);
2080 rStream
.WriteUniOrByteChar( cStrDelim
, eCharSet
);
2084 // This is nasty. The Unicode to byte encoding
2085 // may convert typographical quotation marks to ASCII
2086 // quotation marks, which may interfer with the delimiter,
2087 // so we have to escape delimiters after the string has
2088 // been encoded. Since this may happen also with UTF-8
2089 // encoded typographical quotation marks if such was
2090 // specified as a delimiter we have to check for the full
2091 // encoded delimiter string, not just one character.
2092 // Now for RTL_TEXTENCODING_ISO_2022_... and similar brain
2093 // dead encodings where one code point (and especially a
2094 // low ASCII value) may represent different characters, we
2095 // have to convert forth and back and forth again. Same for
2096 // UTF-7 since it is a context sensitive encoding too.
2098 if ( bContextOrNotAsciiEncoding
)
2101 OString aStrEnc
= OUStringToOString(aUniString
, eCharSet
);
2103 OUString aStrDec
= OStringToOUString(aStrEnc
, eCharSet
);
2105 // search on re-decoded string
2106 bool bNeedQuotes
= false;
2107 sal_Int32 nPos
= getTextSepPos(
2108 aStrDec
, rAsciiOpt
, aStrDelimDecoded
, aDelimDecoded
, bNeedQuotes
);
2110 escapeTextSep
<OUString
, OUStringBuffer
>(
2111 nPos
, aStrDelimDecoded
, aStrDec
);
2113 // write byte re-encoded
2115 rStream
.WriteUniOrByteChar( cStrDelim
, eCharSet
);
2116 rStream
.WriteUnicodeOrByteText( aStrDec
, eCharSet
);
2118 rStream
.WriteUniOrByteChar( cStrDelim
, eCharSet
);
2122 OString aStrEnc
= OUStringToOString(aUniString
, eCharSet
);
2124 // search on encoded string
2125 bool bNeedQuotes
= false;
2126 sal_Int32 nPos
= getTextSepPos(
2127 aStrEnc
, rAsciiOpt
, aStrDelimEncoded
, aDelimEncoded
, bNeedQuotes
);
2129 escapeTextSep
<OString
, OStringBuffer
>(
2130 nPos
, aStrDelimEncoded
, aStrEnc
);
2132 // write byte encoded
2135 aStrDelimEncoded
.getStr(), aStrDelimEncoded
.getLength());
2136 rStream
.Write(aStrEnc
.getStr(), aStrEnc
.getLength());
2139 aStrDelimEncoded
.getStr(), aStrDelimEncoded
.getLength());
2144 rStream
.WriteUnicodeOrByteText( aUniString
);
2147 rStream
.WriteUnicodeOrByteText( aUniString
);
2150 if( nCol
< nEndCol
)
2152 if(cDelim
!=0) //@ BugId 55355
2153 rStream
.WriteUniOrByteChar( cDelim
);
2159 aProgress
.SetStateOnPercent( nRow
);
2162 // write out empty if requested
2163 if ( nNextRow
<= nEndRow
)
2165 for ( nEmptyCol
= nNextCol
; nEmptyCol
< nEndCol
; nEmptyCol
++ )
2166 { // remaining empty columns of last row
2168 lcl_ScDocShell_WriteEmptyFixedWidthString( rStream
,
2169 aDocument
, nTab
, nEmptyCol
);
2170 else if ( cDelim
!= 0 )
2171 rStream
.WriteUniOrByteChar( cDelim
);
2176 for ( nEmptyRow
= nNextRow
; nEmptyRow
<= nEndRow
; nEmptyRow
++ )
2177 { // entire empty rows
2178 for ( nEmptyCol
= nStartCol
; nEmptyCol
< nEndCol
; nEmptyCol
++ )
2181 lcl_ScDocShell_WriteEmptyFixedWidthString( rStream
,
2182 aDocument
, nTab
, nEmptyCol
);
2183 else if ( cDelim
!= 0 )
2184 rStream
.WriteUniOrByteChar( cDelim
);
2189 rStream
.SetStreamCharSet( eOldCharSet
);
2190 rStream
.SetNumberFormatInt( nOldNumberFormatInt
);
2193 bool ScDocShell::ConvertTo( SfxMedium
&rMed
)
2195 ScRefreshTimerProtector
aProt( aDocument
.GetRefreshTimerControlAddress() );
2197 // #i6500# don't call DoEnterHandler here (doesn't work with AutoSave),
2198 // it's already in ExecuteSave (as for Save and SaveAs)
2201 pAutoStyleList
->ExecuteAllNow(); // Execute template timeouts now
2202 if (GetCreateMode()== SFX_CREATE_MODE_STANDARD
)
2203 SfxObjectShell::SetVisArea( Rectangle() ); // Edited normally -> no VisArea
2205 OSL_ENSURE( rMed
.GetFilter(), "Filter == 0" );
2208 OUString aFltName
= rMed
.GetFilter()->GetFilterName();
2210 if (aFltName
.equalsAscii(pFilterXML
))
2212 //TODO/LATER: this shouldn't happen!
2213 OSL_FAIL("XML filter in ConvertFrom?!");
2214 bRet
= SaveXML( &rMed
, NULL
);
2216 else if (aFltName
.equalsAscii(pFilterExcel5
) || aFltName
.equalsAscii(pFilterExcel95
) ||
2217 aFltName
.equalsAscii(pFilterExcel97
) || aFltName
.equalsAscii(pFilterEx5Temp
) ||
2218 aFltName
.equalsAscii(pFilterEx95Temp
) || aFltName
.equalsAscii(pFilterEx97Temp
))
2220 WaitObject
aWait( GetActiveDialogParent() );
2222 bool bDoSave
= true;
2223 if( ScTabViewShell
* pViewShell
= GetBestViewShell() )
2225 ScExtDocOptions
* pExtDocOpt
= aDocument
.GetExtDocOptions();
2227 aDocument
.SetExtDocOptions( pExtDocOpt
= new ScExtDocOptions
);
2228 pViewShell
->GetViewData()->WriteExtOptions( *pExtDocOpt
);
2230 /* #i104990# If the imported document contains a medium
2231 password, determine if we can save it, otherwise ask the users
2232 whether they want to save without it. */
2233 if( (rMed
.GetFilter()->GetFilterFlags() & SFX_FILTER_ENCRYPTION
) == 0 )
2235 SfxItemSet
* pItemSet
= rMed
.GetItemSet();
2236 const SfxPoolItem
* pItem
= 0;
2237 if( pItemSet
&& pItemSet
->GetItemState( SID_PASSWORD
, true, &pItem
) == SFX_ITEM_SET
)
2239 bDoSave
= ScWarnPassword::WarningOnPassword( rMed
);
2240 // #i42858# remove password from medium (warn only one time)
2242 pItemSet
->ClearItem( SID_PASSWORD
);
2248 bool bNeedRetypePassDlg
= ScPassHashHelper::needsPassHashRegen( aDocument
, PASSHASH_XL
);
2249 bDoSave
= !bNeedRetypePassDlg
|| pViewShell
->ExecuteRetypePassDlg( PASSHASH_XL
);
2255 ExportFormatExcel eFormat
= ExpBiff5
;
2256 if( aFltName
.equalsAscii( pFilterExcel97
) || aFltName
.equalsAscii( pFilterEx97Temp
) )
2258 FltError eError
= ScFormatFilter::Get().ScExportExcel5( rMed
, &aDocument
, eFormat
, RTL_TEXTENCODING_MS_1252
);
2260 if( eError
&& !GetError() )
2261 SetError( eError
, OUString( OSL_LOG_PREFIX
) );
2263 // don't return false for warnings
2264 bRet
= ((eError
& ERRCODE_WARNING_MASK
) == ERRCODE_WARNING_MASK
) || (eError
== eERR_OK
);
2268 // export aborted, i.e. "Save without password" warning
2269 SetError( ERRCODE_ABORT
, OUString( OSL_LOG_PREFIX
) );
2272 else if (aFltName
.equalsAscii(pFilterAscii
))
2274 SvStream
* pStream
= rMed
.GetOutStream();
2278 SfxItemSet
* pSet
= rMed
.GetItemSet();
2279 const SfxPoolItem
* pItem
;
2280 if ( pSet
&& SFX_ITEM_SET
==
2281 pSet
->GetItemState( SID_FILE_FILTEROPTIONS
, true, &pItem
) )
2283 sItStr
= ((const SfxStringItem
*)pItem
)->GetValue();
2286 if ( sItStr
.isEmpty() )
2288 // default for ascii export (from API without options):
2289 // ISO8859-1/MS_1252 encoding, comma, double quotes
2291 ScImportOptions
aDefOptions( ',', '"', RTL_TEXTENCODING_MS_1252
);
2292 sItStr
= aDefOptions
.BuildString();
2295 WaitObject
aWait( GetActiveDialogParent() );
2296 ScImportOptions
aOptions( sItStr
);
2297 AsciiSave( *pStream
, aOptions
);
2300 if (aDocument
.GetTableCount() > 1)
2301 if (!rMed
.GetError())
2302 rMed
.SetError(SCWARN_EXPORT_ASCII
, OUString( OSL_LOG_PREFIX
));
2305 else if (aFltName
.equalsAscii(pFilterDBase
))
2308 SfxItemSet
* pSet
= rMed
.GetItemSet();
2309 const SfxPoolItem
* pItem
;
2310 if ( pSet
&& SFX_ITEM_SET
==
2311 pSet
->GetItemState( SID_FILE_FILTEROPTIONS
, true, &pItem
) )
2313 sCharSet
= ((const SfxStringItem
*)pItem
)->GetValue();
2316 if (sCharSet
.isEmpty())
2318 // default for dBase export (from API without options):
2321 sCharSet
= ScGlobal::GetCharsetString( RTL_TEXTENCODING_IBM_850
);
2324 WaitObject
aWait( GetActiveDialogParent() );
2325 // FIXME: Hack so that the Sba opened TempFile can be overwritten
2326 rMed
.CloseOutStream();
2327 bool bHasMemo
= false;
2329 sal_uLong eError
= DBaseExport(
2330 rMed
.GetPhysicalName(), ScGlobal::GetCharsetValue(sCharSet
), bHasMemo
);
2332 if ( eError
!= eERR_OK
&& (eError
& ERRCODE_WARNING_MASK
) )
2337 INetURLObject
aTmpFile( rMed
.GetPhysicalName(), INET_PROT_FILE
);
2339 aTmpFile
.setExtension(OUString("dbt"));
2340 if ( eError
!= eERR_OK
)
2343 SetError(eError
, OUString( OSL_LOG_PREFIX
));
2344 if ( bHasMemo
&& IsDocument( aTmpFile
) )
2345 KillFile( aTmpFile
);
2352 SfxStringItem
* pNameItem
=
2353 (SfxStringItem
*) rMed
.GetItemSet()->GetItem( SID_FILE_NAME
);
2354 INetURLObject
aDbtFile( pNameItem
->GetValue(), INET_PROT_FILE
);
2355 aDbtFile
.setExtension(OUString("dbt"));
2356 if ( IsDocument( aDbtFile
) && !KillFile( aDbtFile
) )
2358 if ( bRet
&& !MoveFile( aTmpFile
, aDbtFile
) )
2362 KillFile( aTmpFile
);
2364 SetError( SCERR_EXPORT_DATA
, OUString( OSL_LOG_PREFIX
) );
2369 else if (aFltName
.equalsAscii(pFilterDif
))
2371 SvStream
* pStream
= rMed
.GetOutStream();
2375 SfxItemSet
* pSet
= rMed
.GetItemSet();
2376 const SfxPoolItem
* pItem
;
2377 if ( pSet
&& SFX_ITEM_SET
==
2378 pSet
->GetItemState( SID_FILE_FILTEROPTIONS
, true, &pItem
) )
2380 sItStr
= ((const SfxStringItem
*)pItem
)->GetValue();
2383 if (sItStr
.isEmpty())
2385 // default for DIF export (from API without options):
2386 // ISO8859-1/MS_1252 encoding
2388 sItStr
= ScGlobal::GetCharsetString( RTL_TEXTENCODING_MS_1252
);
2391 WaitObject
aWait( GetActiveDialogParent() );
2392 ScFormatFilter::Get().ScExportDif( *pStream
, &aDocument
, ScAddress(0,0,0),
2393 ScGlobal::GetCharsetValue(sItStr
) );
2396 if (aDocument
.GetTableCount() > 1)
2397 if (!rMed
.GetError())
2398 rMed
.SetError(SCWARN_EXPORT_ASCII
, OUString( OSL_LOG_PREFIX
));
2401 else if (aFltName
.equalsAscii(pFilterSylk
))
2403 SvStream
* pStream
= rMed
.GetOutStream();
2406 WaitObject
aWait( GetActiveDialogParent() );
2410 aDocument
.GetCellArea( 0, nEndCol
, nEndRow
);
2411 ScRange
aRange( 0,0,0, nEndCol
,nEndRow
,0 );
2413 ScImportExport
aImExport( &aDocument
, aRange
);
2414 aImExport
.SetFormulas( true );
2415 bRet
= aImExport
.ExportStream( *pStream
, rMed
.GetBaseURL( true ), SOT_FORMATSTR_ID_SYLK
);
2418 else if (aFltName
.equalsAscii(pFilterHtml
))
2420 SvStream
* pStream
= rMed
.GetOutStream();
2423 SfxItemSet
* pSet
= rMed
.GetItemSet();
2424 const SfxPoolItem
* pItem
;
2425 OUString sFilterOptions
;
2427 if (pSet
->GetItemState(SID_FILE_FILTEROPTIONS
, true, &pItem
) == SFX_ITEM_SET
)
2428 sFilterOptions
= ((SfxStringItem
*)pItem
)->GetValue();
2430 WaitObject
aWait(GetActiveDialogParent());
2431 ScImportExport
aImExport(&aDocument
);
2432 aImExport
.SetStreamPath(rMed
.GetName());
2433 aImExport
.SetFilterOptions(sFilterOptions
);
2434 bRet
= aImExport
.ExportStream(*pStream
, rMed
.GetBaseURL(true), SOT_FORMATSTR_ID_HTML
);
2435 if (bRet
&& !aImExport
.GetNonConvertibleChars().isEmpty())
2437 SetError(*new StringErrorInfo(
2438 SCWARN_EXPORT_NONCONVERTIBLE_CHARS
,
2439 aImExport
.GetNonConvertibleChars(),
2440 ERRCODE_BUTTON_OK
| ERRCODE_MSG_INFO
), OUString(OSL_LOG_PREFIX
));
2447 SetError(SCERR_IMPORT_NI
, OUString(OSL_LOG_PREFIX
));
2452 bool ScDocShell::SaveCompleted( const uno::Reference
< embed::XStorage
>& xStor
)
2454 return SfxObjectShell::SaveCompleted( xStor
);
2458 bool ScDocShell::DoSaveCompleted( SfxMedium
* pNewStor
)
2460 bool bRet
= SfxObjectShell::DoSaveCompleted( pNewStor
);
2462 // SC_HINT_DOC_SAVED for change ReadOnly -> Read/Write
2463 Broadcast( SfxSimpleHint( SC_HINT_DOC_SAVED
) );
2468 bool ScDocShell::QuerySlotExecutable( sal_uInt16 nSlotId
)
2470 // #i112634# ask VBA event handlers whether to save or print the document
2472 using namespace ::com::sun::star::script::vba
;
2474 sal_Int32 nVbaEventId
= VBAEventId::NO_EVENT
;
2475 uno::Sequence
< uno::Any
> aArgs
;
2480 nVbaEventId
= VBAEventId::WORKBOOK_BEFORESAVE
;
2482 aArgs
[ 0 ] <<= (nSlotId
== SID_SAVEASDOC
);
2485 case SID_PRINTDOCDIRECT
:
2486 nVbaEventId
= VBAEventId::WORKBOOK_BEFOREPRINT
;
2490 bool bSlotExecutable
= true;
2491 if( nVbaEventId
!= VBAEventId::NO_EVENT
) try
2493 uno::Reference
< XVBAEventProcessor
> xEventProcessor( aDocument
.GetVbaEventProcessor(), uno::UNO_QUERY_THROW
);
2494 xEventProcessor
->processVbaEvent( nVbaEventId
, aArgs
);
2496 catch( util::VetoException
& )
2498 bSlotExecutable
= false;
2500 catch( uno::Exception
& )
2503 return bSlotExecutable
;
2507 bool ScDocShell::PrepareClose( bool bUI
)
2509 if(SC_MOD()->GetCurRefDlgId()>0)
2511 SfxViewFrame
* pFrame
= SfxViewFrame::GetFirst( this );
2514 SfxViewShell
* p
= pFrame
->GetViewShell();
2515 ScTabViewShell
* pViewSh
= PTR_CAST(ScTabViewShell
,p
);
2518 Window
*pWin
=pViewSh
->GetWindow();
2519 if(pWin
!=NULL
) pWin
->GrabFocus();
2525 if ( aDocument
.IsInLinkUpdate() || aDocument
.IsInInterpreter() )
2527 ErrorMessage(STR_CLOSE_ERROR_LINK
);
2533 // start 'Workbook_BeforeClose' VBA event handler for possible veto
2534 if( !IsInPrepareClose() )
2538 uno::Reference
< script::vba::XVBAEventProcessor
> xVbaEvents( aDocument
.GetVbaEventProcessor(), uno::UNO_SET_THROW
);
2539 uno::Sequence
< uno::Any
> aArgs
;
2540 xVbaEvents
->processVbaEvent( script::vba::VBAEventId::WORKBOOK_BEFORECLOSE
, aArgs
);
2542 catch( util::VetoException
& )
2544 // if event processor throws VetoException, macro has vetoed close
2547 catch( uno::Exception
& )
2553 bool nRet
= SfxObjectShell::PrepareClose( bUI
);
2554 if (nRet
) // true == close
2555 aDocument
.EnableIdle(false); // Do not mess around with it anymore!
2560 void ScDocShell::PrepareReload()
2562 SfxObjectShell::PrepareReload(); // FIXME: Doesn't do a thing?
2564 // The Disconnect of DDE Links can trigger a Reschedule.
2565 // If the DDE Links are not deleted before the Document dtor,
2566 // the DDE Link Update for this Document can be triggered ofrom this Reschedule on Reload.
2567 // This causes a hang.
2569 // Thus: Disconnect the DDE Links of the old Document before Reload
2570 aDocument
.GetDocLinkManager().disconnectDdeLinks();
2574 OUString
ScDocShell::GetOwnFilterName()
2576 return OUString(pFilterSc50
);
2579 OUString
ScDocShell::GetHtmlFilterName()
2581 return OUString(pFilterHtml
);
2584 OUString
ScDocShell::GetWebQueryFilterName()
2586 return OUString(pFilterHtmlWebQ
);
2589 OUString
ScDocShell::GetAsciiFilterName()
2591 return OUString(pFilterAscii
);
2594 OUString
ScDocShell::GetLotusFilterName()
2596 return OUString(pFilterLotus
);
2599 OUString
ScDocShell::GetDBaseFilterName()
2601 return OUString(pFilterDBase
);
2604 OUString
ScDocShell::GetDifFilterName()
2606 return OUString(pFilterDif
);
2609 bool ScDocShell::HasAutomaticTableName( const OUString
& rFilter
)
2611 // sal_True for those filters that keep the default table name
2612 // (which is language specific)
2614 return rFilter
.equalsAscii( pFilterAscii
)
2615 || rFilter
.equalsAscii( pFilterLotus
)
2616 || rFilter
.equalsAscii( pFilterExcel4
)
2617 || rFilter
.equalsAscii( pFilterEx4Temp
)
2618 || rFilter
.equalsAscii( pFilterDBase
)
2619 || rFilter
.equalsAscii( pFilterDif
)
2620 || rFilter
.equalsAscii( pFilterSylk
)
2621 || rFilter
.equalsAscii( pFilterHtml
)
2622 || rFilter
.equalsAscii( pFilterRtf
);
2625 #if ! ENABLE_TELEPATHY
2626 ScDocFunc
*ScDocShell::CreateDocFunc()
2628 return new ScDocFuncDirect( *this );
2631 ScCollaboration
* ScDocShell::GetCollaboration()
2633 return mpCollaboration
;
2637 ScDocShell::ScDocShell( const ScDocShell
& rShell
) :
2640 SfxObjectShell( rShell
.GetCreateMode() ),
2642 aDocument ( SCDOCMODE_DOCUMENT
, this ),
2643 aDdeTextFmt(OUString("TEXT")),
2644 nPrtToScreenFactor( 1.0 ),
2645 pImpl ( new DocShell_Impl
),
2649 bIsInUndo ( false ),
2650 bDocumentModifiedPending( false ),
2651 bUpdateEnabled ( true ),
2652 nDocumentLock ( 0 ),
2653 nCanUpdate (com::sun::star::document::UpdateDocMode::ACCORDING_TO_CONFIG
),
2654 pOldAutoDBRange ( NULL
),
2655 pDocHelper ( NULL
),
2656 pAutoStyleList ( NULL
),
2657 pPaintLockData ( NULL
),
2658 pSolverSaveData ( NULL
),
2659 pSheetSaveData ( NULL
),
2660 pModificator ( NULL
)
2661 #if ENABLE_TELEPATHY
2662 , mpCollaboration( new ScCollaboration( this ) )
2665 SetPool( &SC_MOD()->GetPool() );
2667 bIsInplace
= rShell
.bIsInplace
;
2669 pDocFunc
= CreateDocFunc();
2671 // SetBaseModel needs exception handling
2672 ScModelObj::CreateAndSet( this );
2674 StartListening(*this);
2675 SfxStyleSheetPool
* pStlPool
= aDocument
.GetStyleSheetPool();
2677 StartListening(*pStlPool
);
2679 GetPageOnFromPageStyleSet( NULL
, 0, bHeaderOn
, bFooterOn
);
2680 SetHelpId( HID_SCSHELL_DOCSH
);
2682 // InitItems and CalcOutputFactor are called now in Load/ConvertFrom/InitNew
2685 ScDocShell::ScDocShell( const sal_uInt64 i_nSfxCreationFlags
) :
2686 SfxObjectShell( i_nSfxCreationFlags
),
2687 aDocument ( SCDOCMODE_DOCUMENT
, this ),
2688 aDdeTextFmt(OUString("TEXT")),
2689 nPrtToScreenFactor( 1.0 ),
2690 pImpl ( new DocShell_Impl
),
2694 bIsInUndo ( false ),
2695 bDocumentModifiedPending( false ),
2696 bUpdateEnabled ( true ),
2697 nDocumentLock ( 0 ),
2698 nCanUpdate (com::sun::star::document::UpdateDocMode::ACCORDING_TO_CONFIG
),
2699 pOldAutoDBRange ( NULL
),
2700 pDocHelper ( NULL
),
2701 pAutoStyleList ( NULL
),
2702 pPaintLockData ( NULL
),
2703 pSolverSaveData ( NULL
),
2704 pSheetSaveData ( NULL
),
2705 pModificator ( NULL
)
2706 #if ENABLE_TELEPATHY
2707 , mpCollaboration( new ScCollaboration( this ) )
2710 SetPool( &SC_MOD()->GetPool() );
2712 bIsInplace
= (GetCreateMode() == SFX_CREATE_MODE_EMBEDDED
);
2713 // Will be reset if not in place
2715 pDocFunc
= CreateDocFunc();
2717 // SetBaseModel needs exception handling
2718 ScModelObj::CreateAndSet( this );
2720 StartListening(*this);
2721 SfxStyleSheetPool
* pStlPool
= aDocument
.GetStyleSheetPool();
2723 StartListening(*pStlPool
);
2724 SetHelpId( HID_SCSHELL_DOCSH
);
2726 aDocument
.GetDBCollection()->SetRefreshHandler(
2727 LINK( this, ScDocShell
, RefreshDBDataHdl
) );
2729 // InitItems and CalcOutputFactor are called now in Load/ConvertFrom/InitNew
2732 ScDocShell::~ScDocShell()
2734 ResetDrawObjectShell(); // If the Drawing Layer still tries to access it, access it
2736 SfxStyleSheetPool
* pStlPool
= aDocument
.GetStyleSheetPool();
2738 EndListening(*pStlPool
);
2739 EndListening(*this);
2741 delete pAutoStyleList
;
2743 SfxApplication
*pSfxApp
= SFX_APP();
2744 if ( pSfxApp
->GetDdeService() ) // Delete DDE for Document
2745 pSfxApp
->RemoveDdeTopic( this );
2748 delete aDocument
.mpUndoManager
;
2749 aDocument
.mpUndoManager
= 0;
2752 delete pPaintLockData
;
2754 delete pSolverSaveData
;
2755 delete pSheetSaveData
;
2756 delete pOldAutoDBRange
;
2760 OSL_FAIL("The Modificator should not exist");
2761 delete pModificator
;
2763 #if ENABLE_TELEPATHY
2764 delete mpCollaboration
;
2768 ::svl::IUndoManager
* ScDocShell::GetUndoManager()
2770 return aDocument
.GetUndoManager();
2773 void ScDocShell::SetModified( bool bModified
)
2775 if ( SfxObjectShell::IsEnableSetModified() )
2777 SfxObjectShell::SetModified( bModified
);
2778 Broadcast( SfxSimpleHint( SFX_HINT_DOCCHANGED
) );
2783 void ScDocShell::SetDocumentModified( bool bIsModified
/* = true */ )
2785 // BroadcastUno must also happen right away with pPaintLockData
2786 // FIXME: Also for SetDrawModified, if Drawing is connected
2787 // FIXME: Then own Hint?
2789 if ( pPaintLockData
&& bIsModified
)
2791 // #i115009# broadcast BCA_BRDCST_ALWAYS, so a component can read recalculated results
2792 // of RecalcModeAlways formulas (like OFFSET) after modifying cells
2793 aDocument
.Broadcast(ScHint(SC_HINT_DATACHANGED
, BCA_BRDCST_ALWAYS
));
2794 aDocument
.InvalidateTableArea(); // #i105279# needed here
2795 aDocument
.BroadcastUno( SfxSimpleHint( SFX_HINT_DATACHANGED
) );
2797 pPaintLockData
->SetModified(); // Later on ...
2801 SetDrawModified( bIsModified
);
2805 if ( aDocument
.IsAutoCalcShellDisabled() )
2806 SetDocumentModifiedPending( true );
2809 SetDocumentModifiedPending( false );
2810 aDocument
.InvalidateStyleSheetUsage();
2811 aDocument
.InvalidateTableArea();
2812 aDocument
.InvalidateLastTableOpParams();
2813 aDocument
.Broadcast(ScHint(SC_HINT_DATACHANGED
, BCA_BRDCST_ALWAYS
));
2814 if ( aDocument
.IsForcedFormulaPending() && aDocument
.GetAutoCalc() )
2815 aDocument
.CalcFormulaTree( true );
2818 // Detective AutoUpdate:
2819 // Update if formulas were modified (DetectiveDirty) or the list contains
2820 // "Trace Error" entries (Trace Error can look completely different
2821 // after changes to non-formula cells).
2823 ScDetOpList
* pList
= aDocument
.GetDetOpList();
2824 if ( pList
&& ( aDocument
.IsDetectiveDirty() || pList
->HasAddError() ) &&
2825 pList
->Count() && !IsInUndo() && SC_MOD()->GetAppOptions().GetDetectiveAuto() )
2827 GetDocFunc().DetectiveRefresh(true); // sal_True = caused by automatic update
2829 aDocument
.SetDetectiveDirty(false); // always reset, also if not refreshed
2832 // notify UNO objects after BCA_BRDCST_ALWAYS etc.
2833 aDocument
.BroadcastUno( SfxSimpleHint( SFX_HINT_DATACHANGED
) );
2838 * SetDrawModified - without Formula update
2840 * Drawing also needs to be updated for the normal SetDocumentModified
2841 * e.g.: when deleting tables etc.
2843 void ScDocShell::SetDrawModified( bool bIsModified
/* = true */ )
2845 bool bUpdate
= bIsModified
!= IsModified();
2847 SetModified( bIsModified
);
2849 SfxBindings
* pBindings
= GetViewBindings();
2854 pBindings
->Invalidate( SID_SAVEDOC
);
2855 pBindings
->Invalidate( SID_DOC_MODIFIED
);
2863 // #i105960# Undo etc used to be volatile.
2864 // They always have to be invalidated, including drawing layer or row height changes
2865 // (but not while pPaintLockData is set).
2866 pBindings
->Invalidate( SID_UNDO
);
2867 pBindings
->Invalidate( SID_REDO
);
2868 pBindings
->Invalidate( SID_REPEAT
);
2871 if ( aDocument
.IsChartListenerCollectionNeedsUpdate() )
2873 aDocument
.UpdateChartListenerCollection();
2874 SFX_APP()->Broadcast(SfxSimpleHint( SC_HINT_DRAW_CHANGED
)); // Navigator
2876 SC_MOD()->AnythingChanged();
2880 void ScDocShell::SetInUndo(bool bSet
)
2886 void ScDocShell::GetDocStat( ScDocStat
& rDocStat
)
2888 SfxPrinter
* pPrinter
= GetPrinter();
2890 aDocument
.GetDocStat( rDocStat
);
2891 rDocStat
.nPageCount
= 0;
2894 for ( SCTAB i
=0; i
<rDocStat
.nTableCount
; i
++ )
2895 rDocStat
.nPageCount
= sal::static_int_cast
<sal_uInt16
>( rDocStat
.nPageCount
+
2896 (sal_uInt16
) ScPrintFunc( this, pPrinter
, i
).GetTotalPages() );
2900 SfxDocumentInfoDialog
* ScDocShell::CreateDocumentInfoDialog(
2901 Window
*pParent
, const SfxItemSet
&rSet
)
2903 SfxDocumentInfoDialog
* pDlg
= new SfxDocumentInfoDialog( pParent
, rSet
);
2904 ScDocShell
* pDocSh
= PTR_CAST(ScDocShell
,SfxObjectShell::Current());
2906 // Only for statistics, if this Doc is shown; not from the Doc Manager
2907 if( pDocSh
== this )
2909 ScAbstractDialogFactory
* pFact
= ScAbstractDialogFactory::Create();
2910 OSL_ENSURE(pFact
, "ScAbstractFactory create fail!");
2911 ::CreateTabPage ScDocStatPageCreate
= pFact
->GetTabPageCreatorFunc( RID_SCPAGE_STAT
);
2912 OSL_ENSURE(ScDocStatPageCreate
, "Tabpage create fail!");
2913 pDlg
->AddFontTabPage();
2914 pDlg
->AddTabPage( 42,
2915 ScGlobal::GetRscString( STR_DOC_STAT
),
2916 ScDocStatPageCreate
,
2922 Window
* ScDocShell::GetActiveDialogParent()
2924 ScTabViewShell
* pViewSh
= ScTabViewShell::GetActiveViewShell();
2926 return pViewSh
->GetDialogParent();
2928 return Application::GetDefDialogParent();
2931 void ScDocShell::SetSolverSaveData( const ScOptSolverSave
& rData
)
2933 delete pSolverSaveData
;
2934 pSolverSaveData
= new ScOptSolverSave( rData
);
2937 ScSheetSaveData
* ScDocShell::GetSheetSaveData()
2939 if (!pSheetSaveData
)
2940 pSheetSaveData
= new ScSheetSaveData
;
2942 return pSheetSaveData
;
2947 void removeKeysIfExists(Reference
<ui::XAcceleratorConfiguration
>& xScAccel
, const vector
<const awt::KeyEvent
*>& rKeys
)
2949 vector
<const awt::KeyEvent
*>::const_iterator itr
= rKeys
.begin(), itrEnd
= rKeys
.end();
2950 for (; itr
!= itrEnd
; ++itr
)
2952 const awt::KeyEvent
* p
= *itr
;
2958 xScAccel
->removeKeyEvent(*p
);
2960 catch (const container::NoSuchElementException
&) {}
2966 void ScDocShell::ResetKeyBindings( ScOptionsUtil::KeyBindingType eType
)
2968 using namespace ::com::sun::star::ui
;
2970 Reference
<uno::XComponentContext
> xContext
= ::comphelper::getProcessComponentContext();
2974 Reference
<XModuleUIConfigurationManagerSupplier
> xModuleCfgSupplier(
2975 theModuleUIConfigurationManagerSupplier::get(xContext
) );
2977 // Grab the Calc configuration.
2978 Reference
<XUIConfigurationManager
> xConfigMgr
=
2979 xModuleCfgSupplier
->getUIConfigurationManager(
2980 OUString("com.sun.star.sheet.SpreadsheetDocument"));
2982 if (!xConfigMgr
.is())
2986 Reference
<XAcceleratorConfiguration
> xScAccel
= xConfigMgr
->getShortCutManager();
2991 vector
<const awt::KeyEvent
*> aKeys
;
2995 awt::KeyEvent aBackspace
;
2996 aBackspace
.KeyCode
= awt::Key::BACKSPACE
;
2997 aBackspace
.Modifiers
= 0;
2998 aKeys
.push_back(&aBackspace
);
3001 awt::KeyEvent aDelete
;
3002 aDelete
.KeyCode
= awt::Key::DELETE
;
3003 aDelete
.Modifiers
= 0;
3004 aKeys
.push_back(&aDelete
);
3007 awt::KeyEvent aCtrlD
;
3008 aCtrlD
.KeyCode
= awt::Key::D
;
3009 aCtrlD
.Modifiers
= awt::KeyModifier::MOD1
;
3010 aKeys
.push_back(&aCtrlD
);
3013 awt::KeyEvent aAltDown
;
3014 aAltDown
.KeyCode
= awt::Key::DOWN
;
3015 aAltDown
.Modifiers
= awt::KeyModifier::MOD2
;
3016 aKeys
.push_back(&aAltDown
);
3018 // Remove all involved keys first, because swapping commands don't work
3019 // well without doing this.
3020 removeKeysIfExists(xScAccel
, aKeys
);
3025 case ScOptionsUtil::KEY_DEFAULT
:
3026 xScAccel
->setKeyEvent(aDelete
, OUString(".uno:ClearContents"));
3027 xScAccel
->setKeyEvent(aBackspace
, OUString(".uno:Delete"));
3028 xScAccel
->setKeyEvent(aCtrlD
, OUString(".uno:FillDown"));
3029 xScAccel
->setKeyEvent(aAltDown
, OUString(".uno:DataSelect"));
3031 case ScOptionsUtil::KEY_OOO_LEGACY
:
3032 xScAccel
->setKeyEvent(aDelete
, OUString(".uno:Delete"));
3033 xScAccel
->setKeyEvent(aBackspace
, OUString(".uno:ClearContents"));
3034 xScAccel
->setKeyEvent(aCtrlD
, OUString(".uno:DataSelect"));
3043 void ScDocShell::UseSheetSaveEntries()
3047 pSheetSaveData
->UseSaveEntries(); // use positions from saved file for next saving
3049 bool bHasEntries
= false;
3050 SCTAB nTabCount
= aDocument
.GetTableCount();
3052 for (nTab
= 0; nTab
< nTabCount
; ++nTab
)
3053 if (pSheetSaveData
->HasStreamPos(nTab
))
3058 // if no positions were set (for example, export to other format),
3059 // reset all "valid" flags
3061 for (nTab
= 0; nTab
< nTabCount
; ++nTab
)
3062 if (aDocument
.IsStreamValid(nTab
))
3063 aDocument
.SetStreamValid(nTab
, false);
3068 // --- ScDocShellModificator ------------------------------------------
3070 ScDocShellModificator::ScDocShellModificator( ScDocShell
& rDS
)
3073 mpProtector(new ScRefreshTimerProtector(rDS
.GetDocument()->GetRefreshTimerControlAddress()))
3075 ScDocument
* pDoc
= rDocShell
.GetDocument();
3076 bAutoCalcShellDisabled
= pDoc
->IsAutoCalcShellDisabled();
3077 bIdleEnabled
= pDoc
->IsIdleEnabled();
3078 pDoc
->SetAutoCalcShellDisabled( true );
3079 pDoc
->EnableIdle(false);
3083 ScDocShellModificator::~ScDocShellModificator()
3085 ScDocument
* pDoc
= rDocShell
.GetDocument();
3086 pDoc
->SetAutoCalcShellDisabled( bAutoCalcShellDisabled
);
3087 if ( !bAutoCalcShellDisabled
&& rDocShell
.IsDocumentModifiedPending() )
3088 rDocShell
.SetDocumentModified(); // last one shuts off the lights
3089 pDoc
->EnableIdle(bIdleEnabled
);
3093 void ScDocShellModificator::SetDocumentModified()
3095 ScDocument
* pDoc
= rDocShell
.GetDocument();
3096 pDoc
->ClearFormulaContext();
3097 if ( !pDoc
->IsImportingXML() )
3099 // AutoCalcShellDisabled temporaer restaurieren
3100 bool bDisabled
= pDoc
->IsAutoCalcShellDisabled();
3101 pDoc
->SetAutoCalcShellDisabled( bAutoCalcShellDisabled
);
3102 rDocShell
.SetDocumentModified();
3103 pDoc
->SetAutoCalcShellDisabled( bDisabled
);
3107 // uno broadcast is necessary for api to work
3108 // -> must also be done during xml import
3109 pDoc
->BroadcastUno( SfxSimpleHint( SFX_HINT_DATACHANGED
) );
3113 bool ScDocShell::IsChangeRecording() const
3115 ScChangeTrack
* pChangeTrack
= aDocument
.GetChangeTrack();
3116 return pChangeTrack
!= NULL
;
3120 bool ScDocShell::HasChangeRecordProtection() const
3123 ScChangeTrack
* pChangeTrack
= aDocument
.GetChangeTrack();
3125 bRes
= pChangeTrack
->IsProtected();
3130 void ScDocShell::SetChangeRecording( bool bActivate
)
3132 bool bOldChangeRecording
= IsChangeRecording();
3136 aDocument
.StartChangeTracking();
3137 ScChangeViewSettings aChangeViewSet
;
3138 aChangeViewSet
.SetShowChanges(true);
3139 aDocument
.SetChangeViewSettings(aChangeViewSet
);
3143 aDocument
.EndChangeTracking();
3147 if (bOldChangeRecording
!= IsChangeRecording())
3149 UpdateAcceptChangesDialog();
3150 // Slots invalidieren
3151 SfxBindings
* pBindings
= GetViewBindings();
3153 pBindings
->InvalidateAll(false);
3158 bool ScDocShell::SetProtectionPassword( const OUString
&rNewPassword
)
3161 ScChangeTrack
* pChangeTrack
= aDocument
.GetChangeTrack();
3164 bool bProtected
= pChangeTrack
->IsProtected();
3166 if (!rNewPassword
.isEmpty())
3168 // when password protection is applied change tracking must always be active
3169 SetChangeRecording( true );
3171 ::com::sun::star::uno::Sequence
< sal_Int8
> aProtectionHash
;
3172 SvPasswordHelper::GetHashPassword( aProtectionHash
, rNewPassword
);
3173 pChangeTrack
->SetProtection( aProtectionHash
);
3177 pChangeTrack
->SetProtection( ::com::sun::star::uno::Sequence
< sal_Int8
>() );
3181 if ( bProtected
!= pChangeTrack
->IsProtected() )
3183 UpdateAcceptChangesDialog();
3184 SetDocumentModified();
3192 bool ScDocShell::GetProtectionHash( /*out*/ ::com::sun::star::uno::Sequence
< sal_Int8
> &rPasswordHash
)
3195 ScChangeTrack
* pChangeTrack
= aDocument
.GetChangeTrack();
3196 if (pChangeTrack
&& pChangeTrack
->IsProtected())
3198 rPasswordHash
= pChangeTrack
->GetProtection();
3204 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */