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 <svl/documentlockfile.hxx>
38 #include <svl/sharecontrolfile.hxx>
39 #include "svl/urihelper.hxx"
40 #include "chgtrack.hxx"
41 #include "chgviset.hxx"
42 #include <com/sun/star/awt/Key.hpp>
43 #include <com/sun/star/awt/KeyModifier.hpp>
44 #include <com/sun/star/container/XContentEnumerationAccess.hpp>
45 #include <com/sun/star/document/UpdateDocMode.hpp>
46 #include <com/sun/star/script/vba/VBAEventId.hpp>
47 #include <com/sun/star/script/vba/XVBAEventProcessor.hpp>
48 #include <com/sun/star/sheet/XSpreadsheetView.hpp>
49 #include <com/sun/star/task/XJob.hpp>
50 #include <com/sun/star/ui/ModuleUIConfigurationManagerSupplier.hpp>
51 #include <com/sun/star/ui/XAcceleratorConfiguration.hpp>
52 #include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
53 #include <com/sun/star/sheet/XSpreadsheet.hpp>
54 #include <com/sun/star/container/XIndexAccess.hpp>
55 #include <com/sun/star/table/XTableChartsSupplier.hpp>
56 #include <com/sun/star/table/XTableCharts.hpp>
57 #include <com/sun/star/table/XTableChart.hpp>
58 #include <com/sun/star/chart2/XChartDocument.hpp>
59 #include <com/sun/star/document/XEmbeddedObjectSupplier.hpp>
60 #include <com/sun/star/frame/XStorable2.hpp>
61 #include <com/sun/star/frame/Desktop.hpp>
63 #include "scabstdlg.hxx"
64 #include <sot/formats.hxx>
66 #include "formulacell.hxx"
71 #include "tabvwsh.hxx"
72 #include "docfunc.hxx"
73 #include "imoptdlg.hxx"
75 #include "scresid.hxx"
77 #include "globstr.hrc"
78 #include "scerrors.hxx"
80 #include "stlpool.hxx"
81 #include "autostyl.hxx"
83 #include "asciiopt.hxx"
84 #include "waitoff.hxx"
85 #include "docpool.hxx"
86 #include "progress.hxx"
87 #include "pntlock.hxx"
89 #include "appoptio.hxx"
90 #include "detdata.hxx"
91 #include "printfun.hxx"
92 #include "dociter.hxx"
93 #include "cellform.hxx"
94 #include "chartlis.hxx"
96 #include "xmlwrap.hxx"
97 #include "drwlayer.hxx"
98 #include "refreshtimer.hxx"
100 #include "scextopt.hxx"
101 #include "compiler.hxx"
102 #include "cfgids.hxx"
103 #include "warnpassword.hxx"
104 #include "optsolver.hxx"
105 #include "sheetdata.hxx"
106 #include "tabprotection.hxx"
107 #include "docparam.hxx"
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>
125 #include <config_telepathy.h>
128 #include "sccollaboration.hxx"
132 #include <boost/shared_ptr.hpp>
134 using namespace com::sun::star
;
135 using ::com::sun::star::uno::Reference
;
136 using ::com::sun::star::uno::UNO_QUERY
;
137 using ::com::sun::star::lang::XMultiServiceFactory
;
138 using ::boost::shared_ptr
;
141 // STATIC DATA -----------------------------------------------------------
143 // Filter-Namen (wie in sclib.cxx)
145 static const sal_Char pFilterSc50
[] = "StarCalc 5.0";
146 static const sal_Char pFilterSc40
[] = "StarCalc 4.0";
147 static const sal_Char pFilterSc30
[] = "StarCalc 3.0";
148 static const sal_Char pFilterSc10
[] = "StarCalc 1.0";
149 static const sal_Char pFilterXML
[] = "StarOffice XML (Calc)";
150 static const sal_Char pFilterAscii
[] = "Text - txt - csv (StarCalc)";
151 static const sal_Char pFilterLotus
[] = "Lotus";
152 static const sal_Char pFilterQPro6
[] = "Quattro Pro 6.0";
153 static const sal_Char pFilterExcel4
[] = "MS Excel 4.0";
154 static const sal_Char pFilterEx4Temp
[] = "MS Excel 4.0 Vorlage/Template";
155 static const sal_Char pFilterExcel5
[] = "MS Excel 5.0/95";
156 static const sal_Char pFilterEx5Temp
[] = "MS Excel 5.0/95 Vorlage/Template";
157 static const sal_Char pFilterExcel95
[] = "MS Excel 95";
158 static const sal_Char pFilterEx95Temp
[] = "MS Excel 95 Vorlage/Template";
159 static const sal_Char pFilterExcel97
[] = "MS Excel 97";
160 static const sal_Char pFilterEx97Temp
[] = "MS Excel 97 Vorlage/Template";
161 static const sal_Char pFilterDBase
[] = "dBase";
162 static const sal_Char pFilterDif
[] = "DIF";
163 static const sal_Char pFilterSylk
[] = "SYLK";
164 static const sal_Char pFilterHtml
[] = "HTML (StarCalc)";
165 static const sal_Char pFilterHtmlWebQ
[] = "calc_HTML_WebQuery";
166 static const sal_Char pFilterRtf
[] = "Rich Text Format (StarCalc)";
168 //----------------------------------------------------------------------
171 #include "scslots.hxx"
174 SFX_IMPL_INTERFACE(ScDocShell
,SfxObjectShell
, ScResId(SCSTR_DOCSHELL
))
178 // GlobalName der aktuellen Version:
179 SFX_IMPL_OBJECTFACTORY( ScDocShell
, SvGlobalName(SO3_SC_CLASSID
), SFXOBJECTSHELL_STD_NORMAL
, "scalc" )
181 TYPEINIT1( ScDocShell
, SfxObjectShell
); // SfxInPlaceObject: kein Type-Info ?
183 //------------------------------------------------------------------
185 void ScDocShell::FillClass( SvGlobalName
* pClassName
,
187 OUString
* /* pAppName */,
188 OUString
* pFullTypeName
,
189 OUString
* pShortTypeName
,
190 sal_Int32 nFileFormat
,
191 sal_Bool bTemplate
/* = sal_False */) const
193 if ( nFileFormat
== SOFFICE_FILEFORMAT_60
)
195 *pClassName
= SvGlobalName( SO3_SC_CLASSID_60
);
196 *pFormat
= SOT_FORMATSTR_ID_STARCALC_60
;
197 *pFullTypeName
= OUString( ScResId( SCSTR_LONG_SCDOC_NAME
) );
198 *pShortTypeName
= OUString( ScResId( SCSTR_SHORT_SCDOC_NAME
) );
200 else if ( nFileFormat
== SOFFICE_FILEFORMAT_8
)
202 *pClassName
= SvGlobalName( SO3_SC_CLASSID_60
);
203 *pFormat
= bTemplate
? SOT_FORMATSTR_ID_STARCALC_8_TEMPLATE
: SOT_FORMATSTR_ID_STARCALC_8
;
204 *pFullTypeName
= "calc8";
205 *pShortTypeName
= ScResId(SCSTR_SHORT_SCDOC_NAME
).toString();
209 OSL_FAIL("wat fuer ne Version?");
213 //------------------------------------------------------------------
215 void ScDocShell::DoEnterHandler()
217 ScTabViewShell
* pViewSh
= ScTabViewShell::GetActiveViewShell();
219 if (pViewSh
->GetViewData()->GetDocShell() == this)
220 SC_MOD()->InputEnterHandler();
223 //------------------------------------------------------------------
225 SCTAB
ScDocShell::GetSaveTab()
228 ScTabViewShell
* pSh
= GetBestViewShell();
231 const ScMarkData
& rMark
= pSh
->GetViewData()->GetMarkData();
232 nTab
= rMark
.GetFirstSelected();
237 sal_uInt16
ScDocShell::GetHiddenInformationState( sal_uInt16 nStates
)
239 // get global state like HIDDENINFORMATION_DOCUMENTVERSIONS
240 sal_uInt16 nState
= SfxObjectShell::GetHiddenInformationState( nStates
);
242 if ( nStates
& HIDDENINFORMATION_RECORDEDCHANGES
)
244 if ( aDocument
.GetChangeTrack() && aDocument
.GetChangeTrack()->GetFirst() )
245 nState
|= HIDDENINFORMATION_RECORDEDCHANGES
;
247 if ( nStates
& HIDDENINFORMATION_NOTES
)
249 SCTAB nTableCount
= aDocument
.GetTableCount();
251 for (SCTAB nTab
= 0; nTab
< nTableCount
&& !bFound
; ++nTab
)
253 if (aDocument
.HasTabNotes(nTab
)) //TODO:
258 nState
|= HIDDENINFORMATION_NOTES
;
264 void ScDocShell::BeforeXMLLoading()
266 aDocument
.EnableIdle(false);
268 // prevent unnecessary broadcasts and updates
269 OSL_ENSURE(pModificator
== NULL
, "The Modificator should not exist");
270 pModificator
= new ScDocShellModificator( *this );
272 aDocument
.SetImportingXML( sal_True
);
273 aDocument
.EnableExecuteLink( false ); // #i101304# to be safe, prevent nested loading from external references
274 aDocument
.EnableUndo( false );
275 // prevent unnecessary broadcasts and "half way listeners"
276 aDocument
.SetInsertingFromOtherDoc( sal_True
);
279 void ScDocShell::AfterXMLLoading(sal_Bool bRet
)
281 if (GetCreateMode() != SFX_CREATE_MODE_ORGANIZER
)
284 // don't prevent establishing of listeners anymore
285 aDocument
.SetInsertingFromOtherDoc( false );
288 ScChartListenerCollection
* pChartListener
= aDocument
.GetChartListenerCollection();
290 pChartListener
->UpdateDirtyCharts();
292 // #95582#; set the table names of linked tables to the new path
293 SCTAB nTabCount
= aDocument
.GetTableCount();
294 for (SCTAB i
= 0; i
< nTabCount
; ++i
)
296 if (aDocument
.IsLinked( i
))
299 aDocument
.GetName(i
, aName
);
300 OUString aLinkTabName
= aDocument
.GetLinkTab(i
);
301 sal_Int32 nLinkTabNameLength
= aLinkTabName
.getLength();
302 sal_Int32 nNameLength
= aName
.getLength();
303 if (nLinkTabNameLength
< nNameLength
)
306 // remove the quottes on begin and end of the docname and restore the escaped quotes
307 const sal_Unicode
* pNameBuffer
= aName
.getStr();
308 if ( *pNameBuffer
== '\'' && // all docnames have to have a ' character on the first pos
309 ScGlobal::UnicodeStrChr( pNameBuffer
, SC_COMPILER_FILE_TAB_SEP
) )
311 OUStringBuffer aDocURLBuffer
;
312 sal_Bool bQuote
= sal_True
; // Dokumentenname ist immer quoted
314 while ( bQuote
&& *pNameBuffer
)
316 if ( *pNameBuffer
== '\'' && *(pNameBuffer
-1) != '\\' )
318 else if( !(*pNameBuffer
== '\\' && *(pNameBuffer
+1) == '\'') )
319 aDocURLBuffer
.append(*pNameBuffer
); // falls escaped Quote: nur Quote in den Namen
324 if( *pNameBuffer
== SC_COMPILER_FILE_TAB_SEP
) // after the last quote of the docname should be the # char
326 xub_StrLen nIndex
= nNameLength
- nLinkTabNameLength
;
327 INetURLObject
aINetURLObject(aDocURLBuffer
.makeStringAndClear());
328 if(aName
== aLinkTabName
.copy(nIndex
, nLinkTabNameLength
) &&
329 (aName
[nIndex
- 1] == '#') && // before the table name should be the # char
330 !aINetURLObject
.HasError()) // the docname should be a valid URL
332 aName
= ScGlobal::GetDocTabName( aDocument
.GetLinkDoc( i
), aDocument
.GetLinkTab( i
) );
333 aDocument
.RenameTab(i
, aName
, sal_True
, sal_True
);
335 // else; nothing has to happen, because it is a user given name
337 // else; nothing has to happen, because it is a user given name
339 // else; nothing has to happen, because it is a user given name
341 // else; nothing has to happen, because it is a user given name
345 // #i94570# DataPilot table names have to be unique, or the tables can't be accessed by API.
346 // If no name (or an invalid name, skipped in ScXMLDataPilotTableContext::EndElement) was set, create a new name.
347 ScDPCollection
* pDPCollection
= aDocument
.GetDPCollection();
350 size_t nDPCount
= pDPCollection
->GetCount();
351 for (size_t nDP
=0; nDP
<nDPCount
; ++nDP
)
353 ScDPObject
* pDPObj
= (*pDPCollection
)[nDP
];
354 if (pDPObj
->GetName().isEmpty())
355 pDPObj
->SetName( pDPCollection
->CreateNewName() );
361 aDocument
.SetInsertingFromOtherDoc( false );
363 aDocument
.SetImportingXML( false );
364 aDocument
.EnableExecuteLink( true );
365 aDocument
.EnableUndo( sal_True
);
370 bool bRecalcState
= aDocument
.GetHardRecalcState();
371 //temporarily set hard-recalc to prevent calling ScFormulaCell::Notify()
372 //which will set the cells dirty.
373 aDocument
.SetHardRecalcState(true);
375 aDocument
.SetHardRecalcState(bRecalcState
);
380 OSL_FAIL("The Modificator should exist");
383 aDocument
.EnableIdle(true);
388 class LoadMediumGuard
391 explicit LoadMediumGuard(ScDocument
* pDoc
) :
394 mpDoc
->SetLoadingMedium(true);
399 mpDoc
->SetLoadingMedium(false);
405 void processDataStream( ScDocShell
& rShell
, const sc::ImportPostProcessData
& rData
)
407 if (!rData
.mpDataStream
)
410 const sc::ImportPostProcessData::DataStream
& r
= *rData
.mpDataStream
;
411 if (!r
.maRange
.IsValid())
414 // Break the streamed range into the top range and the height limit. A
415 // height limit of 0 means unlimited i.e. the streamed data will go all
416 // the way to the last row.
418 ScRange aTopRange
= r
.maRange
;
419 aTopRange
.aEnd
.SetRow(aTopRange
.aStart
.Row());
420 sal_Int32 nLimit
= r
.maRange
.aEnd
.Row() - r
.maRange
.aStart
.Row() + 1;
421 if (r
.maRange
.aEnd
.Row() == MAXROW
)
425 sc::DataStream::MoveType eMove
=
426 r
.meInsertPos
== sc::ImportPostProcessData::DataStream::InsertTop
?
427 sc::DataStream::MOVE_DOWN
: sc::DataStream::RANGE_DOWN
;
429 sc::DataStream
* pStrm
= new sc::DataStream(&rShell
, r
.maURL
, aTopRange
, nLimit
, eMove
, 0);
430 pStrm
->SetRefreshOnEmptyLine(r
.mbRefreshOnEmpty
);
431 sc::DocumentLinkManager
& rMgr
= rShell
.GetDocument()->GetDocLinkManager();
432 rMgr
.setDataStream(pStrm
);
437 sal_Bool
ScDocShell::LoadXML( SfxMedium
* pLoadMedium
, const ::com::sun::star::uno::Reference
< ::com::sun::star::embed::XStorage
>& xStor
)
439 LoadMediumGuard
aLoadGuard(&aDocument
);
441 // MacroCallMode is no longer needed, state is kept in SfxObjectShell now
443 // no Seek(0) here - always loading from storage, GetInStream must not be called
447 // #i62677# BeforeXMLLoading is also called from ScXMLImport::startDocument when invoked
448 // from an external component. The XMLFromWrapper flag is only set here, when called
449 // through ScDocShell.
450 aDocument
.SetXMLFromWrapper( sal_True
);
452 ScXMLImportWrapper
aImport( aDocument
, pLoadMedium
, xStor
);
454 sal_Bool
bRet(false);
455 ErrCode nError
= ERRCODE_NONE
;
456 aDocument
.EnableAdjustHeight(false);
457 if (GetCreateMode() != SFX_CREATE_MODE_ORGANIZER
)
458 bRet
= aImport
.Import(false, nError
);
460 bRet
= aImport
.Import(sal_True
, nError
);
463 pLoadMedium
->SetError( nError
, OUString( OSL_LOG_PREFIX
) );
465 processDataStream(*this, aImport
.GetImportPostProcessData());
467 //if the document was not generated by LibreOffice, do hard recalc in case some other document
468 //generator saved cached formula results that differ from LibreOffice's calculated results or
469 //did not use cached formula results.
470 uno::Reference
<document::XDocumentPropertiesSupplier
> xDPS(GetModel(), uno::UNO_QUERY_THROW
);
471 uno::Reference
<document::XDocumentProperties
> xDocProps
= xDPS
->getDocumentProperties();
473 Reference
<uno::XComponentContext
> xContext
= comphelper::getProcessComponentContext();
474 ScRecalcOptions nRecalcMode
=
475 static_cast<ScRecalcOptions
>(officecfg::Office::Calc::Formula::Load::ODFRecalcMode::get(xContext
));
477 bool bHardRecalc
= false;
478 if (nRecalcMode
== RECALC_ASK
)
480 OUString
sProductName(utl::ConfigManager::getProductName());
481 if (aDocument
.IsUserInteractionEnabled() && xDocProps
->getGenerator().indexOf(sProductName
) == -1)
483 // Generator is not LibreOffice. Ask if the user wants to perform
484 // full re-calculation.
486 GetActiveDialogParent(), WinBits(WB_YES_NO
| WB_DEF_YES
),
487 ScGlobal::GetRscString(STR_QUERY_FORMULA_RECALC_ONLOAD_ODS
));
488 aBox
.SetCheckBoxText(ScGlobal::GetRscString(STR_ALWAYS_PERFORM_SELECTED
));
490 bHardRecalc
= aBox
.Execute() == RET_YES
;
492 if (aBox
.GetCheckBoxState())
494 // Always perform selected action in the future.
495 boost::shared_ptr
< comphelper::ConfigurationChanges
> batch( comphelper::ConfigurationChanges::create() );
496 officecfg::Office::Calc::Formula::Load::ODFRecalcMode::set(sal_Int32(0), batch
);
497 ScFormulaOptions aOpt
= SC_MOD()->GetFormulaOptions();
498 aOpt
.SetODFRecalcOptions(bHardRecalc
? RECALC_ALWAYS
: RECALC_NEVER
);
499 SC_MOD()->SetFormulaOptions(aOpt
);
505 else if (nRecalcMode
== RECALC_ALWAYS
)
512 // still need to recalc volatile formula cells.
513 aDocument
.Broadcast(ScHint(SC_HINT_DATACHANGED
, BCA_BRDCST_ALWAYS
));
516 aDocument
.SetXMLFromWrapper( false );
517 AfterXMLLoading(bRet
);
519 aDocument
.EnableAdjustHeight(true);
523 sal_Bool
ScDocShell::SaveXML( SfxMedium
* pSaveMedium
, const ::com::sun::star::uno::Reference
< ::com::sun::star::embed::XStorage
>& xStor
)
525 aDocument
.EnableIdle(false);
527 ScXMLImportWrapper
aImport( aDocument
, pSaveMedium
, xStor
);
528 sal_Bool
bRet(false);
529 if (GetCreateMode() != SFX_CREATE_MODE_ORGANIZER
)
530 bRet
= aImport
.Export(false);
532 bRet
= aImport
.Export(sal_True
);
534 aDocument
.EnableIdle(true);
539 bool ScDocShell::SaveCurrentChart( SfxMedium
& rMedium
)
546 uno::Reference
< lang::XComponent
> xCurrentComponent
= frame::Desktop::create( comphelper::getProcessComponentContext() )->getCurrentComponent();
548 uno::Reference
< frame::XStorable2
> xStorable( xCurrentComponent
, uno::UNO_QUERY_THROW
);
550 uno::Reference
< frame::XModel
> xChartDoc ( xCurrentComponent
, uno::UNO_QUERY_THROW
);
552 ScXMLChartExportWrapper
aExport( xChartDoc
, rMedium
);
553 bRet
= aExport
.Export();
557 SAL_WARN("sc", "exception thrown while saving chart. Bug!!!");
562 sal_Bool
ScDocShell::Load( SfxMedium
& rMedium
)
564 LoadMediumGuard
aLoadGuard(&aDocument
);
565 ScRefreshTimerProtector
aProt( aDocument
.GetRefreshTimerControlAddress() );
567 // only the latin script language is loaded
568 // -> initialize the others from options (before loading)
571 GetUndoManager()->Clear();
573 sal_Bool bRet
= SfxObjectShell::Load( rMedium
);
578 SFX_ITEMSET_ARG( rMedium
.GetItemSet(), pUpdateDocItem
, SfxUInt16Item
, SID_UPDATEDOCMODE
, false);
579 nCanUpdate
= pUpdateDocItem
? pUpdateDocItem
->GetValue() : com::sun::star::document::UpdateDocMode::NO_UPDATE
;
583 // prepare a valid document for XML filter
584 // (for ConvertFrom, InitNew is called before)
585 aDocument
.MakeTable(0);
586 aDocument
.GetStyleSheetPool()->CreateStandardStyles();
587 aDocument
.UpdStlShtPtrsFrmNms();
589 bRet
= LoadXML( &rMedium
, NULL
);
593 if (!bRet
&& !rMedium
.GetError())
594 rMedium
.SetError( SVSTREAM_FILEFORMAT_ERROR
, OUString( OSL_LOG_PREFIX
) );
596 if (rMedium
.GetError())
597 SetError( rMedium
.GetError(), OUString( OSL_LOG_PREFIX
) );
602 // invalidate eventually temporary table areas
604 aDocument
.InvalidateTableArea();
607 FinishedLoading( SFX_LOADED_MAINDOCUMENT
| SFX_LOADED_IMAGES
);
611 void ScDocShell::Notify( SfxBroadcaster
&, const SfxHint
& rHint
)
613 if (rHint
.ISA(ScTablesHint
) )
615 const ScTablesHint
& rScHint
= static_cast< const ScTablesHint
& >( rHint
);
616 if (rScHint
.GetId() == SC_TAB_INSERTED
)
618 uno::Reference
< script::vba::XVBAEventProcessor
> xVbaEvents
= aDocument
.GetVbaEventProcessor();
619 if ( xVbaEvents
.is() ) try
621 uno::Sequence
< uno::Any
> aArgs( 1 );
622 aArgs
[0] <<= rScHint
.GetTab1();
623 xVbaEvents
->processVbaEvent( script::vba::VBAEventId::WORKBOOK_NEWSHEET
, aArgs
);
625 catch( uno::Exception
& )
631 if (rHint
.ISA(SfxSimpleHint
)) // ohne Parameter
633 sal_uLong nSlot
= ((const SfxSimpleHint
&)rHint
).GetId();
636 case SFX_HINT_TITLECHANGED
:
637 aDocument
.SetName( SfxShell::GetName() );
638 // RegisterNewTargetNames gibts nicht mehr
639 SFX_APP()->Broadcast(SfxSimpleHint( SC_HINT_DOCNAME_CHANGED
)); // Navigator
643 else if (rHint
.ISA(SfxStyleSheetHint
)) // Vorlagen geaendert
644 NotifyStyle((const SfxStyleSheetHint
&) rHint
);
645 else if (rHint
.ISA(ScAutoStyleHint
))
647 //! direct call for AutoStyles
649 // this is called synchronously from ScInterpreter::ScStyle,
650 // modifying the document must be asynchronous
651 // (handled by AddInitial)
653 ScAutoStyleHint
& rStlHint
= (ScAutoStyleHint
&)rHint
;
654 ScRange aRange
= rStlHint
.GetRange();
655 OUString aName1
= rStlHint
.GetStyle1();
656 OUString aName2
= rStlHint
.GetStyle2();
657 sal_uInt32 nTimeout
= rStlHint
.GetTimeout();
660 pAutoStyleList
= new ScAutoStyleList(this);
661 pAutoStyleList
->AddInitial( aRange
, aName1
, nTimeout
, aName2
);
663 else if ( rHint
.ISA( SfxEventHint
) )
665 sal_uLong nEventId
= ((SfxEventHint
&)rHint
).GetEventId();
668 case SFX_EVENT_LOADFINISHED
:
670 #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
671 // the readonly documents should not be opened in shared mode
672 if ( HasSharedXMLFlagSet() && !SC_MOD()->IsInSharedDocLoading() && !IsReadOnly() )
674 if ( SwitchToShared( sal_True
, false ) )
676 ScViewData
* pViewData
= GetViewData();
677 ScTabView
* pTabView
= ( pViewData
? dynamic_cast< ScTabView
* >( pViewData
->GetView() ) : NULL
);
680 pTabView
->UpdateLayerLocks();
685 // switching to shared mode has failed, the document should be opened readonly
686 // TODO/LATER: And error message should be shown here probably
687 SetReadOnlyUI( sal_True
);
693 case SFX_EVENT_VIEWCREATED
:
695 #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
696 if ( IsDocShared() && !SC_MOD()->IsInSharedDocLoading() )
698 ScAppOptions aAppOptions
= SC_MOD()->GetAppOptions();
699 if ( aAppOptions
.GetShowSharedDocumentWarning() )
701 WarningBox
aBox( GetActiveDialogParent(), WinBits( WB_OK
),
702 ScGlobal::GetRscString( STR_SHARED_DOC_WARNING
) );
703 aBox
.SetDefaultCheckBoxText();
705 sal_Bool bChecked
= aBox
.GetCheckBoxState();
708 aAppOptions
.SetShowSharedDocumentWarning( !bChecked
);
709 SC_MOD()->SetAppOptions( aAppOptions
);
716 uno::Reference
< uno::XComponentContext
> xContext(
717 comphelper::getProcessComponentContext() );
718 uno::Reference
< lang::XMultiServiceFactory
> xServiceManager(
719 xContext
->getServiceManager(),
720 uno::UNO_QUERY_THROW
);
721 uno::Reference
< container::XContentEnumerationAccess
> xEnumAccess( xServiceManager
, uno::UNO_QUERY_THROW
);
722 uno::Reference
< container::XEnumeration
> xEnum
= xEnumAccess
->createContentEnumeration(
723 OUString( "com.sun.star.sheet.SpreadsheetDocumentJob" ) );
726 while ( xEnum
->hasMoreElements() )
728 uno::Any aAny
= xEnum
->nextElement();
729 uno::Reference
< lang::XSingleComponentFactory
> xFactory
;
733 uno::Reference
< task::XJob
> xJob( xFactory
->createInstanceWithContext( xContext
), uno::UNO_QUERY_THROW
);
734 uno::Sequence
< beans::NamedValue
> aArgsForJob(1);
735 ScViewData
* pViewData
= GetViewData();
736 SfxViewShell
* pViewShell
= ( pViewData
? pViewData
->GetViewShell() : NULL
);
737 SfxViewFrame
* pViewFrame
= ( pViewShell
? pViewShell
->GetViewFrame() : NULL
);
738 SfxFrame
* pFrame
= ( pViewFrame
? &pViewFrame
->GetFrame() : NULL
);
739 uno::Reference
< frame::XController
> xController
= ( pFrame
? pFrame
->GetController() : 0 );
740 uno::Reference
< sheet::XSpreadsheetView
> xSpreadsheetView( xController
, uno::UNO_QUERY_THROW
);
741 aArgsForJob
[0] = beans::NamedValue( OUString( "SpreadsheetView" ),
742 uno::makeAny( xSpreadsheetView
) );
743 xJob
->execute( aArgsForJob
);
748 catch ( uno::Exception
& )
753 case SFX_EVENT_SAVEDOC
:
755 #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
756 if ( IsDocShared() && !SC_MOD()->IsInSharedDocSaving() )
758 bool bSuccess
= false;
763 uno::Reference
< frame::XModel
> xModel
;
767 xModel
.set( LoadSharedDocument(), uno::UNO_QUERY_THROW
);
768 uno::Reference
< util::XCloseable
> xCloseable( xModel
, uno::UNO_QUERY_THROW
);
770 // check if shared flag is set in shared file
771 bool bShared
= false;
772 ScModelObj
* pDocObj
= ScModelObj::getImplementation( xModel
);
773 ScDocShell
* pSharedDocShell
= ( pDocObj
? dynamic_cast< ScDocShell
* >( pDocObj
->GetObjectShell() ) : NULL
);
774 if ( pSharedDocShell
)
776 bShared
= pSharedDocShell
->HasSharedXMLFlagSet();
779 // #i87870# check if shared status was disabled and enabled again
780 bool bOwnEntry
= false;
781 bool bEntriesNotAccessible
= false;
784 ::svt::ShareControlFile
aControlFile( GetSharedFileURL() );
785 bOwnEntry
= aControlFile
.HasOwnEntry();
787 catch ( uno::Exception
& )
789 bEntriesNotAccessible
= true;
792 if ( bShared
&& bOwnEntry
)
794 uno::Reference
< frame::XStorable
> xStorable( xModel
, uno::UNO_QUERY_THROW
);
796 if ( xStorable
->isReadonly() )
798 xCloseable
->close( sal_True
);
800 OUString
aUserName( ScGlobal::GetRscString( STR_UNKNOWN_USER
) );
801 bool bNoLockAccess
= false;
804 ::svt::DocumentLockFile
aLockFile( GetSharedFileURL() );
805 uno::Sequence
< OUString
> aData
= aLockFile
.GetLockData();
806 if ( aData
.getLength() > LOCKFILE_SYSUSERNAME_ID
)
808 if ( !aData
[LOCKFILE_OOOUSERNAME_ID
].isEmpty() )
810 aUserName
= aData
[LOCKFILE_OOOUSERNAME_ID
];
812 else if ( !aData
[LOCKFILE_SYSUSERNAME_ID
].isEmpty() )
814 aUserName
= aData
[LOCKFILE_SYSUSERNAME_ID
];
818 catch ( uno::Exception
& )
820 bNoLockAccess
= true;
825 // TODO/LATER: in future an error regarding impossibility to open file for writing could be shown
826 ErrorHandler::HandleError( ERRCODE_IO_GENERAL
);
830 OUString
aMessage( ScGlobal::GetRscString( STR_FILE_LOCKED_SAVE_LATER
) );
831 aMessage
= aMessage
.replaceFirst( "%1", aUserName
);
833 WarningBox
aBox( GetActiveDialogParent(), WinBits( WB_RETRY_CANCEL
| WB_DEF_RETRY
), aMessage
);
834 if ( aBox
.Execute() == RET_RETRY
)
842 // merge changes from shared file into temp file
843 bool bSaveToShared
= false;
844 if ( pSharedDocShell
)
846 bSaveToShared
= MergeSharedDocument( pSharedDocShell
);
850 xCloseable
->close( sal_True
);
852 // TODO: keep file lock on shared file
854 // store to shared file
857 bool bChangedViewSettings
= false;
858 ScChangeViewSettings
* pChangeViewSet
= aDocument
.GetChangeViewSettings();
859 if ( pChangeViewSet
&& pChangeViewSet
->ShowChanges() )
861 pChangeViewSet
->SetShowChanges( false );
862 pChangeViewSet
->SetShowAccepted( false );
863 aDocument
.SetChangeViewSettings( *pChangeViewSet
);
864 bChangedViewSettings
= true;
867 uno::Reference
< frame::XStorable
> xStor( GetModel(), uno::UNO_QUERY_THROW
);
868 // TODO/LATER: More entries from the MediaDescriptor might be interesting for the merge
869 uno::Sequence
< beans::PropertyValue
> aValues(1);
870 aValues
[0].Name
= "FilterName";
871 aValues
[0].Value
<<= OUString( GetMedium()->GetFilter()->GetFilterName() );
873 SFX_ITEMSET_ARG( GetMedium()->GetItemSet(), pPasswordItem
, SfxStringItem
, SID_PASSWORD
, false);
874 if ( pPasswordItem
&& !pPasswordItem
->GetValue().isEmpty() )
876 aValues
.realloc( 2 );
877 aValues
[1].Name
= "Password";
878 aValues
[1].Value
<<= pPasswordItem
->GetValue();
881 SC_MOD()->SetInSharedDocSaving( true );
882 xStor
->storeToURL( GetSharedFileURL(), aValues
);
883 SC_MOD()->SetInSharedDocSaving( false );
885 if ( bChangedViewSettings
)
887 pChangeViewSet
->SetShowChanges( sal_True
);
888 pChangeViewSet
->SetShowAccepted( sal_True
);
889 aDocument
.SetChangeViewSettings( *pChangeViewSet
);
894 GetUndoManager()->Clear();
899 xCloseable
->close( sal_True
);
901 if ( bEntriesNotAccessible
)
903 // TODO/LATER: in future an error regarding impossibility to write to share control file could be shown
904 ErrorHandler::HandleError( ERRCODE_IO_GENERAL
);
908 WarningBox
aBox( GetActiveDialogParent(), WinBits( WB_OK
),
909 ScGlobal::GetRscString( STR_DOC_NOLONGERSHARED
) );
912 SfxBindings
* pBindings
= GetViewBindings();
915 pBindings
->ExecuteSynchron( SID_SAVEASDOC
);
920 catch ( uno::Exception
& )
922 OSL_FAIL( "SFX_EVENT_SAVEDOC: caught exception\n" );
923 SC_MOD()->SetInSharedDocSaving( false );
927 uno::Reference
< util::XCloseable
> xClose( xModel
, uno::UNO_QUERY_THROW
);
928 xClose
->close( sal_True
);
930 catch ( uno::Exception
& )
937 SetError( ERRCODE_IO_ABORT
, OUString( OSL_LOG_PREFIX
) ); // this error code will produce no error message, but will break the further saving process
942 pSheetSaveData
->SetInSupportedSave(true);
945 case SFX_EVENT_SAVEASDOC
:
947 if ( GetDocument()->GetExternalRefManager()->containsUnsavedReferences() )
949 WarningBox
aBox( GetActiveDialogParent(), WinBits( WB_YES_NO
),
950 ScGlobal::GetRscString( STR_UNSAVED_EXT_REF
) );
952 if( RET_NO
== aBox
.Execute())
954 SetError( ERRCODE_IO_ABORT
, OUString( OSL_LOG_PREFIX
) ); // this error code will produce no error message, but will break the further saving process
958 case SFX_EVENT_SAVETODOC
:
959 // #i108978# If no event is sent before saving, there will also be no "...DONE" event,
960 // and SAVE/SAVEAS can't be distinguished from SAVETO. So stream copying is only enabled
961 // if there is a SAVE/SAVEAS/SAVETO event first.
963 pSheetSaveData
->SetInSupportedSave(true);
965 case SFX_EVENT_SAVEDOCDONE
:
966 case SFX_EVENT_SAVEASDOCDONE
:
968 // new positions are used after "save" and "save as", but not "save to"
969 UseSheetSaveEntries(); // use positions from saved file for next saving
971 case SFX_EVENT_SAVETODOCDONE
:
972 // only reset the flag, don't use the new positions
974 pSheetSaveData
->SetInSupportedSave(false);
984 // Inhalte fuer Organizer laden
987 sal_Bool
ScDocShell::LoadFrom( SfxMedium
& rMedium
)
989 LoadMediumGuard
aLoadGuard(&aDocument
);
990 ScRefreshTimerProtector
aProt( aDocument
.GetRefreshTimerControlAddress() );
992 WaitObject
aWait( GetActiveDialogParent() );
994 sal_Bool bRet
= false;
998 SFX_ITEMSET_ARG( rMedium
.GetItemSet(), pUpdateDocItem
, SfxUInt16Item
, SID_UPDATEDOCMODE
, false);
999 nCanUpdate
= pUpdateDocItem
? pUpdateDocItem
->GetValue() : com::sun::star::document::UpdateDocMode::NO_UPDATE
;
1002 // until loading/saving only the styles in XML is implemented,
1003 // load the whole file
1004 bRet
= LoadXML( &rMedium
, NULL
);
1007 SfxObjectShell::LoadFrom( rMedium
);
1012 static void lcl_parseHtmlFilterOption(const OUString
& rOption
, LanguageType
& rLang
, bool& rDateConvert
)
1014 OUStringBuffer aBuf
;
1015 std::vector
< OUString
> aTokens
;
1016 sal_Int32 n
= rOption
.getLength();
1017 const sal_Unicode
* p
= rOption
.getStr();
1018 for (sal_Int32 i
= 0; i
< n
; ++i
)
1020 const sal_Unicode c
= p
[i
];
1023 if (!aBuf
.isEmpty())
1024 aTokens
.push_back( aBuf
.makeStringAndClear() );
1030 if (!aBuf
.isEmpty())
1031 aTokens
.push_back( aBuf
.makeStringAndClear() );
1033 rLang
= LanguageType( 0 );
1034 rDateConvert
= false;
1036 if (aTokens
.size() > 0)
1037 rLang
= static_cast<LanguageType
>(aTokens
[0].toInt32());
1038 if (aTokens
.size() > 1)
1039 rDateConvert
= static_cast<bool>(aTokens
[1].toInt32());
1042 sal_Bool
ScDocShell::ConvertFrom( SfxMedium
& rMedium
)
1044 LoadMediumGuard
aLoadGuard(&aDocument
);
1046 sal_Bool bRet
= false; // sal_False heisst Benutzerabbruch !!
1047 // bei Fehler: Fehler am Stream setzen!!
1049 ScRefreshTimerProtector
aProt( aDocument
.GetRefreshTimerControlAddress() );
1051 GetUndoManager()->Clear();
1053 // ob nach dem Import optimale Spaltenbreiten gesetzt werden sollen
1054 sal_Bool bSetColWidths
= false;
1055 sal_Bool bSetSimpleTextColWidths
= false;
1056 ScColWidthParam aColWidthParam
[MAXCOLCOUNT
];
1057 ScRange aColWidthRange
;
1058 // ob nach dem Import optimale Zeilenhoehen gesetzt werden sollen
1059 sal_Bool bSetRowHeights
= false;
1061 vector
<ScDocRowHeightUpdater::TabRanges
> aRecalcRowRangesArray
;
1063 // Alle Filter brauchen die komplette Datei am Stueck (nicht asynchron),
1064 // darum vorher per CreateFileStream dafuer sorgen, dass die komplette
1065 // Datei uebertragen wird.
1066 rMedium
.GetPhysicalName(); //! CreateFileStream direkt rufen, wenn verfuegbar
1068 SFX_ITEMSET_ARG( rMedium
.GetItemSet(), pUpdateDocItem
, SfxUInt16Item
, SID_UPDATEDOCMODE
, false);
1069 nCanUpdate
= pUpdateDocItem
? pUpdateDocItem
->GetValue() : com::sun::star::document::UpdateDocMode::NO_UPDATE
;
1071 const SfxFilter
* pFilter
= rMedium
.GetFilter();
1074 OUString aFltName
= pFilter
->GetFilterName();
1076 sal_Bool bCalc3
= ( aFltName
.equalsAscii(pFilterSc30
) );
1077 sal_Bool bCalc4
= ( aFltName
.equalsAscii(pFilterSc40
) );
1078 if (!bCalc3
&& !bCalc4
)
1079 aDocument
.SetInsertingFromOtherDoc( sal_True
);
1081 if (aFltName
.equalsAscii(pFilterXML
))
1082 bRet
= LoadXML( &rMedium
, NULL
);
1083 else if (aFltName
.equalsAscii(pFilterSc10
))
1085 SvStream
* pStream
= rMedium
.GetInStream();
1088 FltError eError
= ScFormatFilter::Get().ScImportStarCalc10( *pStream
, &aDocument
);
1089 if (eError
!= eERR_OK
)
1092 SetError(eError
, OUString( OSL_LOG_PREFIX
));
1098 else if (aFltName
.equalsAscii(pFilterLotus
))
1101 SfxItemSet
* pSet
= rMedium
.GetItemSet();
1102 const SfxPoolItem
* pItem
;
1103 if ( pSet
&& SFX_ITEM_SET
==
1104 pSet
->GetItemState( SID_FILE_FILTEROPTIONS
, sal_True
, &pItem
) )
1106 sItStr
= ((const SfxStringItem
*)pItem
)->GetValue();
1109 if (sItStr
.isEmpty())
1111 // default for lotus import (from API without options):
1113 sItStr
= ScGlobal::GetCharsetString( RTL_TEXTENCODING_IBM_437
);
1116 FltError eError
= ScFormatFilter::Get().ScImportLotus123( rMedium
, &aDocument
,
1117 ScGlobal::GetCharsetValue(sItStr
));
1118 if (eError
!= eERR_OK
)
1121 SetError(eError
, OUString( OSL_LOG_PREFIX
));
1123 if( ( eError
& ERRCODE_WARNING_MASK
) == ERRCODE_WARNING_MASK
)
1128 bSetColWidths
= sal_True
;
1129 bSetRowHeights
= sal_True
;
1131 else if ( aFltName
.equalsAscii(pFilterExcel4
) || aFltName
.equalsAscii(pFilterExcel5
) ||
1132 aFltName
.equalsAscii(pFilterExcel95
) || aFltName
.equalsAscii(pFilterExcel97
) ||
1133 aFltName
.equalsAscii(pFilterEx4Temp
) || aFltName
.equalsAscii(pFilterEx5Temp
) ||
1134 aFltName
.equalsAscii(pFilterEx95Temp
) || aFltName
.equalsAscii(pFilterEx97Temp
) )
1136 EXCIMPFORMAT eFormat
= EIF_AUTO
;
1137 if ( aFltName
.equalsAscii(pFilterExcel4
) || aFltName
.equalsAscii(pFilterEx4Temp
) )
1138 eFormat
= EIF_BIFF_LE4
;
1139 else if ( aFltName
.equalsAscii(pFilterExcel5
) || aFltName
.equalsAscii(pFilterExcel95
) ||
1140 aFltName
.equalsAscii(pFilterEx5Temp
) || aFltName
.equalsAscii(pFilterEx95Temp
) )
1141 eFormat
= EIF_BIFF5
;
1142 else if ( aFltName
.equalsAscii(pFilterExcel97
) || aFltName
.equalsAscii(pFilterEx97Temp
) )
1143 eFormat
= EIF_BIFF8
;
1145 MakeDrawLayer(); //! im Filter
1146 CalcOutputFactor(); // prepare update of row height
1147 FltError eError
= ScFormatFilter::Get().ScImportExcel( rMedium
, &aDocument
, eFormat
);
1148 aDocument
.UpdateFontCharSet();
1149 if ( aDocument
.IsChartListenerCollectionNeedsUpdate() )
1150 aDocument
.UpdateChartListenerCollection(); //! fuer alle Importe?
1152 // all graphics objects must have names
1153 aDocument
.EnsureGraphicNames();
1155 if (eError
== SCWARN_IMPORT_RANGE_OVERFLOW
)
1158 SetError(eError
, OUString( OSL_LOG_PREFIX
));
1161 else if (eError
!= eERR_OK
)
1164 SetError(eError
, OUString( OSL_LOG_PREFIX
));
1169 else if (aFltName
.equalsAscii(pFilterAscii
))
1171 SfxItemSet
* pSet
= rMedium
.GetItemSet();
1172 const SfxPoolItem
* pItem
;
1173 ScAsciiOptions aOptions
;
1174 sal_Bool bOptInit
= false;
1176 if ( pSet
&& SFX_ITEM_SET
==
1177 pSet
->GetItemState( SID_FILE_FILTEROPTIONS
, sal_True
, &pItem
) )
1179 aOptions
.ReadFromString( ((const SfxStringItem
*)pItem
)->GetValue() );
1180 bOptInit
= sal_True
;
1185 // default for ascii import (from API without options):
1186 // ISO8859-1/MS_1252 encoding, comma, double quotes
1188 aOptions
.SetCharSet( RTL_TEXTENCODING_MS_1252
);
1189 aOptions
.SetFieldSeps( OUString(',') );
1190 aOptions
.SetTextSep( '"' );
1193 FltError eError
= eERR_OK
;
1194 bool bOverflowRow
, bOverflowCol
, bOverflowCell
;
1195 bOverflowRow
= bOverflowCol
= bOverflowCell
= false;
1197 if( ! rMedium
.IsStorage() )
1199 ScImportExport
aImpEx( &aDocument
);
1200 aImpEx
.SetExtOptions( aOptions
);
1202 SvStream
* pInStream
= rMedium
.GetInStream();
1205 pInStream
->SetStreamCharSet( aOptions
.GetCharSet() );
1206 pInStream
->Seek( 0 );
1207 bRet
= aImpEx
.ImportStream( *pInStream
, rMedium
.GetBaseURL() );
1208 eError
= bRet
? eERR_OK
: SCERR_IMPORT_CONNECT
;
1209 aDocument
.StartAllListeners();
1210 aDocument
.SetDirty();
1211 bOverflowRow
= aImpEx
.IsOverflowRow();
1212 bOverflowCol
= aImpEx
.IsOverflowCol();
1213 bOverflowCell
= aImpEx
.IsOverflowCell();
1217 OSL_FAIL( "No Stream" );
1221 if (eError
!= eERR_OK
)
1224 SetError(eError
, OUString( OSL_LOG_PREFIX
));
1226 else if (!GetError() && (bOverflowRow
|| bOverflowCol
|| bOverflowCell
))
1228 // precedence: row, column, cell
1229 FltError nWarn
= (bOverflowRow
? SCWARN_IMPORT_ROW_OVERFLOW
:
1230 (bOverflowCol
? SCWARN_IMPORT_COLUMN_OVERFLOW
:
1231 SCWARN_IMPORT_CELL_OVERFLOW
));
1232 SetError( nWarn
, OUString( OSL_LOG_PREFIX
));
1234 bSetColWidths
= sal_True
;
1235 bSetSimpleTextColWidths
= sal_True
;
1237 else if (aFltName
.equalsAscii(pFilterDBase
))
1240 SfxItemSet
* pSet
= rMedium
.GetItemSet();
1241 const SfxPoolItem
* pItem
;
1242 if ( pSet
&& SFX_ITEM_SET
==
1243 pSet
->GetItemState( SID_FILE_FILTEROPTIONS
, sal_True
, &pItem
) )
1245 sItStr
= ((const SfxStringItem
*)pItem
)->GetValue();
1248 if (sItStr
.isEmpty())
1250 // default for dBase import (from API without options):
1253 sItStr
= ScGlobal::GetCharsetString( RTL_TEXTENCODING_IBM_850
);
1256 ScDocRowHeightUpdater::TabRanges
aRecalcRanges(0);
1257 sal_uLong eError
= DBaseImport( rMedium
.GetPhysicalName(),
1258 ScGlobal::GetCharsetValue(sItStr
), aColWidthParam
, *aRecalcRanges
.mpRanges
);
1259 aRecalcRowRangesArray
.push_back(aRecalcRanges
);
1261 if (eError
!= eERR_OK
)
1264 SetError(eError
, OUString( OSL_LOG_PREFIX
));
1265 bRet
= ( eError
== SCWARN_IMPORT_RANGE_OVERFLOW
);
1270 aColWidthRange
.aStart
.SetRow( 1 ); // Spaltenheader nicht
1271 bSetColWidths
= true;
1272 bSetSimpleTextColWidths
= true;
1274 else if (aFltName
.equalsAscii(pFilterDif
))
1276 SvStream
* pStream
= rMedium
.GetInStream();
1281 SfxItemSet
* pSet
= rMedium
.GetItemSet();
1282 const SfxPoolItem
* pItem
;
1283 if ( pSet
&& SFX_ITEM_SET
==
1284 pSet
->GetItemState( SID_FILE_FILTEROPTIONS
, sal_True
, &pItem
) )
1286 sItStr
= ((const SfxStringItem
*)pItem
)->GetValue();
1289 if (sItStr
.isEmpty())
1291 // default for DIF import (from API without options):
1292 // ISO8859-1/MS_1252 encoding
1294 sItStr
= ScGlobal::GetCharsetString( RTL_TEXTENCODING_MS_1252
);
1297 eError
= ScFormatFilter::Get().ScImportDif( *pStream
, &aDocument
, ScAddress(0,0,0),
1298 ScGlobal::GetCharsetValue(sItStr
));
1299 if (eError
!= eERR_OK
)
1302 SetError(eError
, OUString( OSL_LOG_PREFIX
));
1304 if( ( eError
& ERRCODE_WARNING_MASK
) == ERRCODE_WARNING_MASK
)
1310 bSetColWidths
= sal_True
;
1311 bSetSimpleTextColWidths
= sal_True
;
1312 bSetRowHeights
= sal_True
;
1314 else if (aFltName
.equalsAscii(pFilterSylk
))
1316 FltError eError
= SCERR_IMPORT_UNKNOWN
;
1317 if( !rMedium
.IsStorage() )
1319 ScImportExport
aImpEx( &aDocument
);
1321 SvStream
* pInStream
= rMedium
.GetInStream();
1324 pInStream
->Seek( 0 );
1325 bRet
= aImpEx
.ImportStream( *pInStream
, rMedium
.GetBaseURL(), SOT_FORMATSTR_ID_SYLK
);
1326 eError
= bRet
? eERR_OK
: SCERR_IMPORT_UNKNOWN
;
1327 aDocument
.StartAllListeners();
1328 aDocument
.SetDirty();
1332 OSL_FAIL( "No Stream" );
1336 if ( eError
!= eERR_OK
&& !GetError() )
1337 SetError(eError
, OUString( OSL_LOG_PREFIX
));
1338 bSetColWidths
= sal_True
;
1339 bSetSimpleTextColWidths
= sal_True
;
1340 bSetRowHeights
= sal_True
;
1342 else if (aFltName
.equalsAscii(pFilterQPro6
))
1344 FltError eError
= ScFormatFilter::Get().ScImportQuattroPro( rMedium
, &aDocument
);
1345 if (eError
!= eERR_OK
)
1348 SetError( eError
, OUString( OSL_LOG_PREFIX
) );
1349 if( ( eError
& ERRCODE_WARNING_MASK
) == ERRCODE_WARNING_MASK
)
1354 // TODO: Filter should set column widths. Not doing it here, it may
1355 // result in very narrow or wide columns, depending on content.
1356 // Setting row heights makes cells with font size attribution or
1357 // wrapping enabled look nicer..
1358 bSetRowHeights
= sal_True
;
1360 else if (aFltName
.equalsAscii(pFilterRtf
))
1362 FltError eError
= SCERR_IMPORT_UNKNOWN
;
1363 if( !rMedium
.IsStorage() )
1365 SvStream
* pInStream
= rMedium
.GetInStream();
1368 pInStream
->Seek( 0 );
1370 eError
= ScFormatFilter::Get().ScImportRTF( *pInStream
, rMedium
.GetBaseURL(), &aDocument
, aRange
);
1371 if (eError
!= eERR_OK
)
1374 SetError(eError
, OUString( OSL_LOG_PREFIX
));
1376 if( ( eError
& ERRCODE_WARNING_MASK
) == ERRCODE_WARNING_MASK
)
1381 aDocument
.StartAllListeners();
1382 aDocument
.SetDirty();
1383 bSetColWidths
= sal_True
;
1384 bSetRowHeights
= sal_True
;
1388 OSL_FAIL( "No Stream" );
1392 if ( eError
!= eERR_OK
&& !GetError() )
1393 SetError(eError
, OUString( OSL_LOG_PREFIX
));
1395 else if (aFltName
.equalsAscii(pFilterHtml
) || aFltName
.equalsAscii(pFilterHtmlWebQ
))
1397 FltError eError
= SCERR_IMPORT_UNKNOWN
;
1398 sal_Bool bWebQuery
= aFltName
.equalsAscii(pFilterHtmlWebQ
);
1399 if( !rMedium
.IsStorage() )
1401 SvStream
* pInStream
= rMedium
.GetInStream();
1404 LanguageType eLang
= LANGUAGE_SYSTEM
;
1405 bool bDateConvert
= false;
1406 SfxItemSet
* pSet
= rMedium
.GetItemSet();
1407 const SfxPoolItem
* pItem
;
1408 if ( pSet
&& SFX_ITEM_SET
==
1409 pSet
->GetItemState( SID_FILE_FILTEROPTIONS
, sal_True
, &pItem
) )
1411 OUString aFilterOption
= (static_cast<const SfxStringItem
*>(pItem
))->GetValue();
1412 lcl_parseHtmlFilterOption(aFilterOption
, eLang
, bDateConvert
);
1415 pInStream
->Seek( 0 );
1417 // HTML macht eigenes ColWidth/RowHeight
1419 SvNumberFormatter
aNumFormatter( comphelper::getProcessComponentContext(), eLang
);
1420 eError
= ScFormatFilter::Get().ScImportHTML( *pInStream
, rMedium
.GetBaseURL(), &aDocument
, aRange
,
1421 GetOutputFactor(), !bWebQuery
, &aNumFormatter
, bDateConvert
);
1422 if (eError
!= eERR_OK
)
1425 SetError(eError
, OUString( OSL_LOG_PREFIX
));
1427 if( ( eError
& ERRCODE_WARNING_MASK
) == ERRCODE_WARNING_MASK
)
1432 aDocument
.StartAllListeners();
1433 aDocument
.SetDirty();
1437 OSL_FAIL( "No Stream" );
1441 if ( eError
!= eERR_OK
&& !GetError() )
1442 SetError(eError
, OUString( OSL_LOG_PREFIX
));
1447 SetError(SCERR_IMPORT_NI
, OUString( OSL_LOG_PREFIX
));
1451 aDocument
.SetInsertingFromOtherDoc( false );
1455 OSL_FAIL("Kein Filter bei ConvertFrom");
1460 if ( bRet
&& (bSetColWidths
|| bSetRowHeights
) )
1461 { // Spaltenbreiten/Zeilenhoehen anpassen, Basis 100% Zoom
1462 Fraction
aZoom( 1, 1 );
1463 double nPPTX
= ScGlobal::nScreenPPTX
* (double) aZoom
1464 / GetOutputFactor(); // Faktor ist Drucker zu Bildschirm
1465 double nPPTY
= ScGlobal::nScreenPPTY
* (double) aZoom
;
1466 VirtualDevice aVirtDev
;
1467 // all sheets (for Excel import)
1468 SCTAB nTabCount
= aDocument
.GetTableCount();
1469 for (SCTAB nTab
=0; nTab
<nTabCount
; nTab
++)
1473 aDocument
.GetCellArea( nTab
, nEndCol
, nEndRow
);
1474 aColWidthRange
.aEnd
.SetCol( nEndCol
);
1475 aColWidthRange
.aEnd
.SetRow( nEndRow
);
1477 aMark
.SetMarkArea( aColWidthRange
);
1478 aMark
.MarkToMulti();
1479 // Reihenfolge erst Breite dann Hoehe ist wichtig (vergl. hund.rtf)
1480 if ( bSetColWidths
)
1482 for ( SCCOL nCol
=0; nCol
<= nEndCol
; nCol
++ )
1484 if (!bSetSimpleTextColWidths
)
1485 aColWidthParam
[nCol
].mbSimpleText
= false;
1487 sal_uInt16 nWidth
= aDocument
.GetOptimalColWidth(
1488 nCol
, nTab
, &aVirtDev
, nPPTX
, nPPTY
, aZoom
, aZoom
, false, &aMark
,
1489 &aColWidthParam
[nCol
] );
1490 aDocument
.SetColWidth( nCol
, nTab
,
1491 nWidth
+ (sal_uInt16
)ScGlobal::nLastColWidthExtra
);
1498 // Update all rows in all tables.
1499 ScSizeDeviceProvider
aProv(this);
1500 ScDocRowHeightUpdater
aUpdater(aDocument
, aProv
.GetDevice(), aProv
.GetPPTX(), aProv
.GetPPTY(), NULL
);
1503 else if (!aRecalcRowRangesArray
.empty())
1505 // Update only specified row ranges for better performance.
1506 ScSizeDeviceProvider
aProv(this);
1507 ScDocRowHeightUpdater
aUpdater(aDocument
, aProv
.GetDevice(), aProv
.GetPPTX(), aProv
.GetPPTY(), &aRecalcRowRangesArray
);
1511 FinishedLoading( SFX_LOADED_MAINDOCUMENT
| SFX_LOADED_IMAGES
);
1514 // invalidate eventually temporary table areas
1516 aDocument
.InvalidateTableArea();
1523 bool ScDocShell::LoadExternal( SfxMedium
& rMed
)
1525 const SfxFilter
* pFilter
= rMed
.GetFilter();
1529 if (pFilter
->GetProviderName() == "orcus")
1531 ScOrcusFilters
* pOrcus
= ScFormatFilter::Get().GetOrcusFilters();
1535 const OUString
& rFilterName
= pFilter
->GetName();
1536 if (rFilterName
== "gnumeric")
1538 if (!pOrcus
->importGnumeric(aDocument
, rMed
))
1541 else if (rFilterName
== "csv")
1543 if (!pOrcus
->importCSV(aDocument
, rMed
))
1546 else if (rFilterName
== "xlsx")
1548 if (!pOrcus
->importXLSX(aDocument
, rMed
))
1551 else if (rFilterName
== "ods")
1553 if (!pOrcus
->importODS(aDocument
, rMed
))
1557 FinishedLoading(SFX_LOADED_MAINDOCUMENT
| SFX_LOADED_IMAGES
);
1565 ScDocShell::PrepareSaveGuard::PrepareSaveGuard( ScDocShell
& rDocShell
)
1566 : mrDocShell( rDocShell
)
1568 // DoEnterHandler not here (because of AutoSave), is in ExecuteSave.
1570 ScChartListenerCollection
* pCharts
= mrDocShell
.aDocument
.GetChartListenerCollection();
1572 pCharts
->UpdateDirtyCharts(); // Charts to be updated.
1573 mrDocShell
.aDocument
.StopTemporaryChartLock();
1574 if (mrDocShell
.pAutoStyleList
)
1575 mrDocShell
.pAutoStyleList
->ExecuteAllNow(); // Execute template timeouts now.
1576 if (mrDocShell
.aDocument
.HasExternalRefManager())
1578 ScExternalRefManager
* pRefMgr
= mrDocShell
.aDocument
.GetExternalRefManager();
1579 if (pRefMgr
&& pRefMgr
->hasExternalData())
1581 pRefMgr
->setAllCacheTableReferencedStati( false);
1582 mrDocShell
.aDocument
.MarkUsedExternalReferences(); // Mark tables of external references to be written.
1585 if (mrDocShell
.GetCreateMode()== SFX_CREATE_MODE_STANDARD
)
1586 mrDocShell
.SfxObjectShell::SetVisArea( Rectangle() ); // "Normally" worked on => no VisArea.
1589 ScDocShell::PrepareSaveGuard::~PrepareSaveGuard()
1591 if (mrDocShell
.aDocument
.HasExternalRefManager())
1593 ScExternalRefManager
* pRefMgr
= mrDocShell
.aDocument
.GetExternalRefManager();
1594 if (pRefMgr
&& pRefMgr
->hasExternalData())
1596 // Prevent accidental data loss due to lack of knowledge.
1597 pRefMgr
->setAllCacheTableReferencedStati( true);
1603 sal_Bool
ScDocShell::Save()
1605 ScRefreshTimerProtector
aProt( aDocument
.GetRefreshTimerControlAddress() );
1607 PrepareSaveGuard
aPrepareGuard( *this);
1609 // wait cursor is handled with progress bar
1610 sal_Bool bRet
= SfxObjectShell::Save();
1612 bRet
= SaveXML( GetMedium(), NULL
);
1619 * Remove the file name from the full path, to keep only the directory path.
1621 void popFileName(OUString
& rPath
)
1623 if (!rPath
.isEmpty())
1625 INetURLObject
aURLObj(rPath
);
1626 aURLObj
.removeSegment();
1627 rPath
= aURLObj
.GetMainURL(INetURLObject::NO_DECODE
);
1633 sal_Bool
ScDocShell::SaveAs( SfxMedium
& rMedium
)
1635 OUString aCurPath
; // empty for new document that hasn't been saved.
1636 const SfxMedium
* pCurMedium
= GetMedium();
1639 aCurPath
= pCurMedium
->GetName();
1640 popFileName(aCurPath
);
1643 if (!aCurPath
.isEmpty())
1645 // current document has a path -> not a brand-new document.
1646 OUString aNewPath
= rMedium
.GetName();
1647 popFileName(aNewPath
);
1648 OUString aRel
= URIHelper::simpleNormalizedMakeRelative(aCurPath
, aNewPath
);
1649 if (!aRel
.isEmpty())
1651 // Directory path will change before and after the save.
1652 aDocument
.InvalidateStreamOnSave();
1656 ScTabViewShell
* pViewShell
= GetBestViewShell();
1657 bool bNeedsRehash
= ScPassHashHelper::needsPassHashRegen(aDocument
, PASSHASH_SHA1
);
1659 // legacy xls hash double-hashed by SHA1 is also supported.
1660 bNeedsRehash
= ScPassHashHelper::needsPassHashRegen(aDocument
, PASSHASH_XL
, PASSHASH_SHA1
);
1662 if (pViewShell
&& bNeedsRehash
)
1664 if (!pViewShell
->ExecuteRetypePassDlg(PASSHASH_SHA1
))
1665 // password re-type cancelled. Don't save the document.
1670 ScRefreshTimerProtector
aProt( aDocument
.GetRefreshTimerControlAddress() );
1672 PrepareSaveGuard
aPrepareGuard( *this);
1674 OUString aFltName
= rMedium
.GetFilter()->GetFilterName();
1675 bool bChartExport
= aFltName
.indexOf("chart8") != -1;
1677 // wait cursor is handled with progress bar
1678 sal_Bool bRet
= false;
1681 bRet
= SfxObjectShell::SaveAs( rMedium
);
1682 bRet
= SaveXML( &rMedium
, NULL
);
1686 bRet
= SaveCurrentChart( rMedium
);
1693 sal_Bool
ScDocShell::IsInformationLost()
1695 //!!! bei Gelegenheit ein korrekte eigene Behandlung einbauen
1697 return SfxObjectShell::IsInformationLost();
1702 // Xcl-like column width measured in characters of standard font.
1703 sal_Int32
lcl_ScDocShell_GetColWidthInChars( sal_uInt16 nWidth
)
1711 return sal_Int32( f
);
1715 void lcl_ScDocShell_GetFixedWidthString( OUString
& rStr
, const ScDocument
& rDoc
,
1716 SCTAB nTab
, SCCOL nCol
, sal_Bool bValue
, SvxCellHorJustify eHorJust
)
1718 OUString aString
= rStr
;
1719 sal_Int32 nLen
= lcl_ScDocShell_GetColWidthInChars(
1720 rDoc
.GetColWidth( nCol
, nTab
) );
1721 //If the text won't fit in the column
1722 if ( nLen
< aString
.getLength() )
1724 OUStringBuffer aReplacement
;
1726 aReplacement
.append("###");
1728 aReplacement
.append(aString
);
1729 //truncate to the number of characters that should fit, even in the
1730 //bValue case nLen might be < len ###
1731 aString
= comphelper::string::truncateToLength(aReplacement
, nLen
).makeStringAndClear();
1733 if ( nLen
> aString
.getLength() )
1735 if ( bValue
&& eHorJust
== SVX_HOR_JUSTIFY_STANDARD
)
1736 eHorJust
= SVX_HOR_JUSTIFY_RIGHT
;
1737 sal_Int32 nBlanks
= nLen
- aString
.getLength();
1740 case SVX_HOR_JUSTIFY_RIGHT
:
1742 OUStringBuffer aTmp
;
1743 aTmp
= comphelper::string::padToLength( aTmp
, nBlanks
, ' ' );
1744 aString
= aTmp
.append(aString
).makeStringAndClear();
1747 case SVX_HOR_JUSTIFY_CENTER
:
1749 sal_Int32 nLeftPad
= nBlanks
/ 2;
1750 OUStringBuffer aTmp
;
1751 comphelper::string::padToLength( aTmp
, nLeftPad
, ' ' );
1752 aTmp
.append(aString
);
1753 comphelper::string::padToLength( aTmp
, nLen
, ' ' );
1754 aString
= aTmp
.makeStringAndClear();
1759 OUStringBuffer
aTmp(aString
);
1760 comphelper::string::padToLength( aTmp
, nLen
, ' ' );
1761 aString
= aTmp
.makeStringAndClear();
1769 void lcl_ScDocShell_WriteEmptyFixedWidthString( SvStream
& rStream
,
1770 const ScDocument
& rDoc
, SCTAB nTab
, SCCOL nCol
)
1773 lcl_ScDocShell_GetFixedWidthString( aString
, rDoc
, nTab
, nCol
, false,
1774 SVX_HOR_JUSTIFY_STANDARD
);
1775 rStream
.WriteUnicodeOrByteText( aString
);
1778 template<typename StrT
, typename SepCharT
>
1779 sal_Int32
getTextSepPos(
1780 const StrT
& rStr
, const ScImportOptions
& rAsciiOpt
, const SepCharT
& rTextSep
, const SepCharT
& rFieldSep
, bool& rNeedQuotes
)
1782 // #i116636# quotes are needed if text delimiter (quote), field delimiter,
1783 // or LF is in the cell text.
1784 sal_Int32 nPos
= rStr
.indexOf(rTextSep
);
1785 rNeedQuotes
= rAsciiOpt
.bQuoteAllText
|| (nPos
>= 0) ||
1786 (rStr
.indexOf(rFieldSep
) >= 0) ||
1787 (rStr
.indexOf('\n') >= 0);
1791 template<typename StrT
, typename StrBufT
>
1792 void escapeTextSep(sal_Int32 nPos
, const StrT
& rStrDelim
, StrT
& rStr
)
1797 aBuf
.insert(nPos
, rStrDelim
);
1798 rStr
= aBuf
.makeStringAndClear();
1799 nPos
= rStr
.indexOf(rStrDelim
, nPos
+1+rStrDelim
.getLength());
1805 void ScDocShell::AsciiSave( SvStream
& rStream
, const ScImportOptions
& rAsciiOpt
)
1807 sal_Unicode cDelim
= rAsciiOpt
.nFieldSepCode
;
1808 sal_Unicode cStrDelim
= rAsciiOpt
.nTextSepCode
;
1809 rtl_TextEncoding eCharSet
= rAsciiOpt
.eCharSet
;
1810 bool bFixedWidth
= rAsciiOpt
.bFixedWidth
;
1811 bool bSaveAsShown
= rAsciiOpt
.bSaveAsShown
;
1812 bool bShowFormulas
= rAsciiOpt
.bSaveFormulas
;
1814 rtl_TextEncoding eOldCharSet
= rStream
.GetStreamCharSet();
1815 rStream
.SetStreamCharSet( eCharSet
);
1816 sal_uInt16 nOldNumberFormatInt
= rStream
.GetNumberFormatInt();
1817 OString aStrDelimEncoded
; // only used if not Unicode
1818 OUString aStrDelimDecoded
; // only used if context encoding
1819 OString aDelimEncoded
;
1820 OUString aDelimDecoded
;
1821 bool bContextOrNotAsciiEncoding
;
1822 if ( eCharSet
== RTL_TEXTENCODING_UNICODE
)
1824 rStream
.StartWritingUnicodeText();
1825 bContextOrNotAsciiEncoding
= false;
1829 aStrDelimEncoded
= OString(&cStrDelim
, 1, eCharSet
);
1830 aDelimEncoded
= OString(&cDelim
, 1, eCharSet
);
1831 rtl_TextEncodingInfo aInfo
;
1832 aInfo
.StructSize
= sizeof(aInfo
);
1833 if ( rtl_getTextEncodingInfo( eCharSet
, &aInfo
) )
1835 bContextOrNotAsciiEncoding
=
1836 (((aInfo
.Flags
& RTL_TEXTENCODING_INFO_CONTEXT
) != 0) ||
1837 ((aInfo
.Flags
& RTL_TEXTENCODING_INFO_ASCII
) == 0));
1838 if ( bContextOrNotAsciiEncoding
)
1840 aStrDelimDecoded
= OStringToOUString(aStrDelimEncoded
, eCharSet
);
1841 aDelimDecoded
= OStringToOUString(aDelimEncoded
, eCharSet
);
1845 bContextOrNotAsciiEncoding
= false;
1848 SCCOL nStartCol
= 0;
1849 SCROW nStartRow
= 0;
1850 SCTAB nTab
= GetSaveTab();
1853 aDocument
.GetCellArea( nTab
, nEndCol
, nEndRow
);
1855 ScProgress
aProgress( this, ScGlobal::GetRscString( STR_SAVE_DOC
), nEndRow
);
1859 bool bTabProtect
= aDocument
.IsTabProtected( nTab
);
1863 SCCOL nNextCol
= nStartCol
;
1864 SCROW nNextRow
= nStartRow
;
1867 SvNumberFormatter
& rFormatter
= *aDocument
.GetFormatTable();
1869 ScHorizontalCellIterator
aIter( &aDocument
, nTab
, nStartCol
, nStartRow
,
1871 ScRefCellValue
* pCell
;
1872 while ( ( pCell
= aIter
.GetNext( nCol
, nRow
) ) != NULL
)
1874 bool bProgress
= false; // only upon line change
1875 if ( nNextRow
< nRow
)
1876 { // empty rows or/and empty columns up to end of row
1878 for ( nEmptyCol
= nNextCol
; nEmptyCol
< nEndCol
; nEmptyCol
++ )
1879 { // remaining columns of last row
1881 lcl_ScDocShell_WriteEmptyFixedWidthString( rStream
,
1882 aDocument
, nTab
, nEmptyCol
);
1883 else if ( cDelim
!= 0 )
1884 rStream
.WriteUniOrByteChar( cDelim
);
1888 for ( nEmptyRow
= nNextRow
; nEmptyRow
< nRow
; nEmptyRow
++ )
1889 { // completely empty rows
1890 for ( nEmptyCol
= nStartCol
; nEmptyCol
< nEndCol
; nEmptyCol
++ )
1893 lcl_ScDocShell_WriteEmptyFixedWidthString( rStream
,
1894 aDocument
, nTab
, nEmptyCol
);
1895 else if ( cDelim
!= 0 )
1896 rStream
.WriteUniOrByteChar( cDelim
);
1900 for ( nEmptyCol
= nStartCol
; nEmptyCol
< nCol
; nEmptyCol
++ )
1901 { // empty columns at beginning of row
1903 lcl_ScDocShell_WriteEmptyFixedWidthString( rStream
,
1904 aDocument
, nTab
, nEmptyCol
);
1905 else if ( cDelim
!= 0 )
1906 rStream
.WriteUniOrByteChar( cDelim
);
1910 else if ( nNextCol
< nCol
)
1911 { // empty columns in same row
1912 for ( nEmptyCol
= nNextCol
; nEmptyCol
< nCol
; nEmptyCol
++ )
1913 { // columns in between
1915 lcl_ScDocShell_WriteEmptyFixedWidthString( rStream
,
1916 aDocument
, nTab
, nEmptyCol
);
1917 else if ( cDelim
!= 0 )
1918 rStream
.WriteUniOrByteChar( cDelim
);
1921 if ( nCol
== nEndCol
)
1924 nNextCol
= nStartCol
;
1925 nNextRow
= nRow
+ 1;
1928 nNextCol
= nCol
+ 1;
1930 CellType eType
= pCell
->meType
;
1931 ScAddress
aPos(nCol
, nRow
, nTab
);
1934 const ScProtectionAttr
* pProtAttr
=
1935 (const ScProtectionAttr
*) aDocument
.GetAttr(
1936 nCol
, nRow
, nTab
, ATTR_PROTECTION
);
1937 if ( pProtAttr
->GetHideCell() ||
1938 ( eType
== CELLTYPE_FORMULA
&& bShowFormulas
&&
1939 pProtAttr
->GetHideFormula() ) )
1940 eType
= CELLTYPE_NONE
; // hide
1949 case CELLTYPE_FORMULA
:
1951 sal_uInt16 nErrCode
;
1952 if ( bShowFormulas
)
1954 pCell
->mpFormula
->GetFormula(aString
);
1957 else if ((nErrCode
= pCell
->mpFormula
->GetErrCode()) != 0)
1959 aString
= ScGlobal::GetErrorString( nErrCode
);
1962 else if (pCell
->mpFormula
->IsValue())
1964 sal_uInt32 nFormat
= aDocument
.GetNumberFormat(aPos
);
1965 if ( bFixedWidth
|| bSaveAsShown
)
1968 aString
= ScCellFormat::GetString(aDocument
, aPos
, nFormat
, &pDummy
, rFormatter
);
1969 bString
= bSaveAsShown
&& rFormatter
.IsTextFormat( nFormat
);
1973 ScCellFormat::GetInputString(*pCell
, nFormat
, aString
, rFormatter
, &aDocument
);
1981 sal_uInt32 nFormat
= aDocument
.GetNumberFormat(aPos
);
1983 aString
= ScCellFormat::GetString(aDocument
, aPos
, nFormat
, &pDummy
, rFormatter
);
1986 aString
= pCell
->mpFormula
->GetString().getString();
1991 case CELLTYPE_STRING
:
1994 sal_uInt32 nFormat
= aDocument
.GetNumberFormat(aPos
);
1996 aString
= ScCellFormat::GetString(aDocument
, aPos
, nFormat
, &pDummy
, rFormatter
);
1999 aString
= pCell
->mpString
->getString();
2002 case CELLTYPE_EDIT
:
2004 const EditTextObject
* pObj
= pCell
->mpEditText
;
2005 EditEngine
& rEngine
= aDocument
.GetEditEngine();
2006 rEngine
.SetText( *pObj
);
2007 aString
= rEngine
.GetText(); // including LF
2011 case CELLTYPE_VALUE
:
2014 aDocument
.GetNumberFormat( nCol
, nRow
, nTab
, nFormat
);
2015 if ( bFixedWidth
|| bSaveAsShown
)
2018 aString
= ScCellFormat::GetString(aDocument
, aPos
, nFormat
, &pDummy
, rFormatter
);
2019 bString
= bSaveAsShown
&& rFormatter
.IsTextFormat( nFormat
);
2023 ScCellFormat::GetInputString(*pCell
, nFormat
, aString
, rFormatter
, &aDocument
);
2029 OSL_FAIL( "ScDocShell::AsciiSave: unknown CellType" );
2036 SvxCellHorJustify eHorJust
= (SvxCellHorJustify
)
2037 ((const SvxHorJustifyItem
*) aDocument
.GetAttr( nCol
, nRow
,
2038 nTab
, ATTR_HOR_JUSTIFY
))->GetValue();
2039 lcl_ScDocShell_GetFixedWidthString( aString
, aDocument
, nTab
, nCol
,
2040 !bString
, eHorJust
);
2041 rStream
.WriteUnicodeOrByteText( aString
);
2045 OUString aUniString
= aString
;//remove that later
2046 if (!bString
&& cStrDelim
!= 0 && !aUniString
.isEmpty())
2048 sal_Unicode c
= aUniString
[0];
2049 bString
= (c
== cStrDelim
|| c
== ' ' ||
2050 aUniString
.endsWith(" ") ||
2051 aUniString
.indexOf(cStrDelim
) >= 0);
2052 if (!bString
&& cDelim
!= 0)
2053 bString
= (aUniString
.indexOf(cDelim
) >= 0);
2057 if ( cStrDelim
!= 0 ) //@ BugId 55355
2059 if ( eCharSet
== RTL_TEXTENCODING_UNICODE
)
2061 bool bNeedQuotes
= false;
2062 sal_Int32 nPos
= getTextSepPos(
2063 aUniString
, rAsciiOpt
, cStrDelim
, cDelim
, bNeedQuotes
);
2065 escapeTextSep
<OUString
, OUStringBuffer
>(
2066 nPos
, OUString(cStrDelim
), aUniString
);
2069 rStream
.WriteUniOrByteChar( cStrDelim
, eCharSet
);
2070 write_uInt16s_FromOUString(rStream
, aUniString
);
2072 rStream
.WriteUniOrByteChar( cStrDelim
, eCharSet
);
2076 // This is nasty. The Unicode to byte encoding
2077 // may convert typographical quotation marks to ASCII
2078 // quotation marks, which may interfer with the delimiter,
2079 // so we have to escape delimiters after the string has
2080 // been encoded. Since this may happen also with UTF-8
2081 // encoded typographical quotation marks if such was
2082 // specified as a delimiter we have to check for the full
2083 // encoded delimiter string, not just one character.
2084 // Now for RTL_TEXTENCODING_ISO_2022_... and similar brain
2085 // dead encodings where one code point (and especially a
2086 // low ASCII value) may represent different characters, we
2087 // have to convert forth and back and forth again. Same for
2088 // UTF-7 since it is a context sensitive encoding too.
2090 if ( bContextOrNotAsciiEncoding
)
2093 OString aStrEnc
= OUStringToOString(aUniString
, eCharSet
);
2095 OUString aStrDec
= OStringToOUString(aStrEnc
, eCharSet
);
2097 // search on re-decoded string
2098 bool bNeedQuotes
= false;
2099 sal_Int32 nPos
= getTextSepPos(
2100 aStrDec
, rAsciiOpt
, aStrDelimDecoded
, aDelimDecoded
, bNeedQuotes
);
2102 escapeTextSep
<OUString
, OUStringBuffer
>(
2103 nPos
, aStrDelimDecoded
, aStrDec
);
2105 // write byte re-encoded
2107 rStream
.WriteUniOrByteChar( cStrDelim
, eCharSet
);
2108 rStream
.WriteUnicodeOrByteText( aStrDec
, eCharSet
);
2110 rStream
.WriteUniOrByteChar( cStrDelim
, eCharSet
);
2114 OString aStrEnc
= OUStringToOString(aUniString
, eCharSet
);
2116 // search on encoded string
2117 bool bNeedQuotes
= false;
2118 sal_Int32 nPos
= getTextSepPos(
2119 aStrEnc
, rAsciiOpt
, aStrDelimEncoded
, aDelimEncoded
, bNeedQuotes
);
2121 escapeTextSep
<OString
, OStringBuffer
>(
2122 nPos
, aStrDelimEncoded
, aStrEnc
);
2124 // write byte encoded
2127 aStrDelimEncoded
.getStr(), aStrDelimEncoded
.getLength());
2128 rStream
.Write(aStrEnc
.getStr(), aStrEnc
.getLength());
2131 aStrDelimEncoded
.getStr(), aStrDelimEncoded
.getLength());
2136 rStream
.WriteUnicodeOrByteText( aUniString
);
2139 rStream
.WriteUnicodeOrByteText( aUniString
);
2142 if( nCol
< nEndCol
)
2144 if(cDelim
!=0) //@ BugId 55355
2145 rStream
.WriteUniOrByteChar( cDelim
);
2151 aProgress
.SetStateOnPercent( nRow
);
2154 // write out empty if requested
2155 if ( nNextRow
<= nEndRow
)
2157 for ( nEmptyCol
= nNextCol
; nEmptyCol
< nEndCol
; nEmptyCol
++ )
2158 { // remaining empty columns of last row
2160 lcl_ScDocShell_WriteEmptyFixedWidthString( rStream
,
2161 aDocument
, nTab
, nEmptyCol
);
2162 else if ( cDelim
!= 0 )
2163 rStream
.WriteUniOrByteChar( cDelim
);
2168 for ( nEmptyRow
= nNextRow
; nEmptyRow
<= nEndRow
; nEmptyRow
++ )
2169 { // entire empty rows
2170 for ( nEmptyCol
= nStartCol
; nEmptyCol
< nEndCol
; nEmptyCol
++ )
2173 lcl_ScDocShell_WriteEmptyFixedWidthString( rStream
,
2174 aDocument
, nTab
, nEmptyCol
);
2175 else if ( cDelim
!= 0 )
2176 rStream
.WriteUniOrByteChar( cDelim
);
2181 rStream
.SetStreamCharSet( eOldCharSet
);
2182 rStream
.SetNumberFormatInt( nOldNumberFormatInt
);
2185 sal_Bool
ScDocShell::ConvertTo( SfxMedium
&rMed
)
2187 ScRefreshTimerProtector
aProt( aDocument
.GetRefreshTimerControlAddress() );
2189 // #i6500# don't call DoEnterHandler here (doesn't work with AutoSave),
2190 // it's already in ExecuteSave (as for Save and SaveAs)
2193 pAutoStyleList
->ExecuteAllNow(); // Vorlagen-Timeouts jetzt ausfuehren
2194 if (GetCreateMode()== SFX_CREATE_MODE_STANDARD
)
2195 SfxObjectShell::SetVisArea( Rectangle() ); // normal bearbeitet -> keine VisArea
2197 OSL_ENSURE( rMed
.GetFilter(), "Filter == 0" );
2199 sal_Bool bRet
= false;
2200 OUString aFltName
= rMed
.GetFilter()->GetFilterName();
2202 if (aFltName
.equalsAscii(pFilterXML
))
2204 //TODO/LATER: this shouldn't happen!
2205 OSL_FAIL("XML filter in ConvertFrom?!");
2206 bRet
= SaveXML( &rMed
, NULL
);
2208 else if (aFltName
.equalsAscii(pFilterExcel5
) || aFltName
.equalsAscii(pFilterExcel95
) ||
2209 aFltName
.equalsAscii(pFilterExcel97
) || aFltName
.equalsAscii(pFilterEx5Temp
) ||
2210 aFltName
.equalsAscii(pFilterEx95Temp
) || aFltName
.equalsAscii(pFilterEx97Temp
))
2212 WaitObject
aWait( GetActiveDialogParent() );
2214 bool bDoSave
= true;
2215 if( ScTabViewShell
* pViewShell
= GetBestViewShell() )
2217 ScExtDocOptions
* pExtDocOpt
= aDocument
.GetExtDocOptions();
2219 aDocument
.SetExtDocOptions( pExtDocOpt
= new ScExtDocOptions
);
2220 pViewShell
->GetViewData()->WriteExtOptions( *pExtDocOpt
);
2222 /* #i104990# If the imported document contains a medium
2223 password, determine if we can save it, otherwise ask the users
2224 whether they want to save without it. */
2225 if( (rMed
.GetFilter()->GetFilterFlags() & SFX_FILTER_ENCRYPTION
) == 0 )
2227 SfxItemSet
* pItemSet
= rMed
.GetItemSet();
2228 const SfxPoolItem
* pItem
= 0;
2229 if( pItemSet
&& pItemSet
->GetItemState( SID_PASSWORD
, sal_True
, &pItem
) == SFX_ITEM_SET
)
2231 bDoSave
= ScWarnPassword::WarningOnPassword( rMed
);
2232 // #i42858# remove password from medium (warn only one time)
2234 pItemSet
->ClearItem( SID_PASSWORD
);
2240 bool bNeedRetypePassDlg
= ScPassHashHelper::needsPassHashRegen( aDocument
, PASSHASH_XL
);
2241 bDoSave
= !bNeedRetypePassDlg
|| pViewShell
->ExecuteRetypePassDlg( PASSHASH_XL
);
2247 ExportFormatExcel eFormat
= ExpBiff5
;
2248 if( aFltName
.equalsAscii( pFilterExcel97
) || aFltName
.equalsAscii( pFilterEx97Temp
) )
2250 FltError eError
= ScFormatFilter::Get().ScExportExcel5( rMed
, &aDocument
, eFormat
, RTL_TEXTENCODING_MS_1252
);
2252 if( eError
&& !GetError() )
2253 SetError( eError
, OUString( OSL_LOG_PREFIX
) );
2255 // don't return false for warnings
2256 bRet
= ((eError
& ERRCODE_WARNING_MASK
) == ERRCODE_WARNING_MASK
) || (eError
== eERR_OK
);
2260 // export aborted, i.e. "Save without password" warning
2261 SetError( ERRCODE_ABORT
, OUString( OSL_LOG_PREFIX
) );
2264 else if (aFltName
.equalsAscii(pFilterAscii
))
2266 SvStream
* pStream
= rMed
.GetOutStream();
2270 SfxItemSet
* pSet
= rMed
.GetItemSet();
2271 const SfxPoolItem
* pItem
;
2272 if ( pSet
&& SFX_ITEM_SET
==
2273 pSet
->GetItemState( SID_FILE_FILTEROPTIONS
, sal_True
, &pItem
) )
2275 sItStr
= ((const SfxStringItem
*)pItem
)->GetValue();
2278 if ( sItStr
.isEmpty() )
2280 // default for ascii export (from API without options):
2281 // ISO8859-1/MS_1252 encoding, comma, double quotes
2283 ScImportOptions
aDefOptions( ',', '"', RTL_TEXTENCODING_MS_1252
);
2284 sItStr
= aDefOptions
.BuildString();
2287 WaitObject
aWait( GetActiveDialogParent() );
2288 ScImportOptions
aOptions( sItStr
);
2289 AsciiSave( *pStream
, aOptions
);
2292 if (aDocument
.GetTableCount() > 1)
2293 if (!rMed
.GetError())
2294 rMed
.SetError(SCWARN_EXPORT_ASCII
, OUString( OSL_LOG_PREFIX
));
2297 else if (aFltName
.equalsAscii(pFilterDBase
))
2300 SfxItemSet
* pSet
= rMed
.GetItemSet();
2301 const SfxPoolItem
* pItem
;
2302 if ( pSet
&& SFX_ITEM_SET
==
2303 pSet
->GetItemState( SID_FILE_FILTEROPTIONS
, sal_True
, &pItem
) )
2305 sCharSet
= ((const SfxStringItem
*)pItem
)->GetValue();
2308 if (sCharSet
.isEmpty())
2310 // default for dBase export (from API without options):
2313 sCharSet
= ScGlobal::GetCharsetString( RTL_TEXTENCODING_IBM_850
);
2316 WaitObject
aWait( GetActiveDialogParent() );
2317 // HACK damit Sba geoffnetes TempFile ueberschreiben kann
2318 rMed
.CloseOutStream();
2319 bool bHasMemo
= false;
2321 sal_uLong eError
= DBaseExport(
2322 rMed
.GetPhysicalName(), ScGlobal::GetCharsetValue(sCharSet
), bHasMemo
);
2324 if ( eError
!= eERR_OK
&& (eError
& ERRCODE_WARNING_MASK
) )
2329 INetURLObject
aTmpFile( rMed
.GetPhysicalName(), INET_PROT_FILE
);
2331 aTmpFile
.setExtension(OUString("dbt"));
2332 if ( eError
!= eERR_OK
)
2335 SetError(eError
, OUString( OSL_LOG_PREFIX
));
2336 if ( bHasMemo
&& IsDocument( aTmpFile
) )
2337 KillFile( aTmpFile
);
2344 SfxStringItem
* pNameItem
=
2345 (SfxStringItem
*) rMed
.GetItemSet()->GetItem( SID_FILE_NAME
);
2346 INetURLObject
aDbtFile( pNameItem
->GetValue(), INET_PROT_FILE
);
2347 aDbtFile
.setExtension(OUString("dbt"));
2348 if ( IsDocument( aDbtFile
) && !KillFile( aDbtFile
) )
2350 if ( bRet
&& !MoveFile( aTmpFile
, aDbtFile
) )
2354 KillFile( aTmpFile
);
2356 SetError( SCERR_EXPORT_DATA
, OUString( OSL_LOG_PREFIX
) );
2361 else if (aFltName
.equalsAscii(pFilterDif
))
2363 SvStream
* pStream
= rMed
.GetOutStream();
2367 SfxItemSet
* pSet
= rMed
.GetItemSet();
2368 const SfxPoolItem
* pItem
;
2369 if ( pSet
&& SFX_ITEM_SET
==
2370 pSet
->GetItemState( SID_FILE_FILTEROPTIONS
, sal_True
, &pItem
) )
2372 sItStr
= ((const SfxStringItem
*)pItem
)->GetValue();
2375 if (sItStr
.isEmpty())
2377 // default for DIF export (from API without options):
2378 // ISO8859-1/MS_1252 encoding
2380 sItStr
= ScGlobal::GetCharsetString( RTL_TEXTENCODING_MS_1252
);
2383 WaitObject
aWait( GetActiveDialogParent() );
2384 ScFormatFilter::Get().ScExportDif( *pStream
, &aDocument
, ScAddress(0,0,0),
2385 ScGlobal::GetCharsetValue(sItStr
) );
2388 if (aDocument
.GetTableCount() > 1)
2389 if (!rMed
.GetError())
2390 rMed
.SetError(SCWARN_EXPORT_ASCII
, OUString( OSL_LOG_PREFIX
));
2393 else if (aFltName
.equalsAscii(pFilterSylk
))
2395 SvStream
* pStream
= rMed
.GetOutStream();
2398 WaitObject
aWait( GetActiveDialogParent() );
2402 aDocument
.GetCellArea( 0, nEndCol
, nEndRow
);
2403 ScRange
aRange( 0,0,0, nEndCol
,nEndRow
,0 );
2405 ScImportExport
aImExport( &aDocument
, aRange
);
2406 aImExport
.SetFormulas( sal_True
);
2407 bRet
= aImExport
.ExportStream( *pStream
, rMed
.GetBaseURL( true ), SOT_FORMATSTR_ID_SYLK
);
2410 else if (aFltName
.equalsAscii(pFilterHtml
))
2412 SvStream
* pStream
= rMed
.GetOutStream();
2415 WaitObject
aWait( GetActiveDialogParent() );
2416 ScImportExport
aImExport( &aDocument
);
2417 aImExport
.SetStreamPath( rMed
.GetName() );
2418 bRet
= aImExport
.ExportStream( *pStream
, rMed
.GetBaseURL( true ), SOT_FORMATSTR_ID_HTML
);
2419 if ( bRet
&& !aImExport
.GetNonConvertibleChars().isEmpty() )
2420 SetError( *new StringErrorInfo(
2421 SCWARN_EXPORT_NONCONVERTIBLE_CHARS
,
2422 aImExport
.GetNonConvertibleChars(),
2423 ERRCODE_BUTTON_OK
| ERRCODE_MSG_INFO
), OUString( OSL_LOG_PREFIX
) );
2429 SetError(SCERR_IMPORT_NI
, OUString( OSL_LOG_PREFIX
) );
2435 sal_Bool
ScDocShell::SaveCompleted( const uno::Reference
< embed::XStorage
>& xStor
)
2437 return SfxObjectShell::SaveCompleted( xStor
);
2441 sal_Bool
ScDocShell::DoSaveCompleted( SfxMedium
* pNewStor
)
2443 sal_Bool bRet
= SfxObjectShell::DoSaveCompleted( pNewStor
);
2445 // SC_HINT_DOC_SAVED fuer Wechsel ReadOnly -> Read/Write
2446 Broadcast( SfxSimpleHint( SC_HINT_DOC_SAVED
) );
2451 sal_Bool
ScDocShell::QuerySlotExecutable( sal_uInt16 nSlotId
)
2453 // #i112634# ask VBA event handlers whether to save or print the document
2455 using namespace ::com::sun::star::script::vba
;
2457 sal_Int32 nVbaEventId
= VBAEventId::NO_EVENT
;
2458 uno::Sequence
< uno::Any
> aArgs
;
2463 nVbaEventId
= VBAEventId::WORKBOOK_BEFORESAVE
;
2465 aArgs
[ 0 ] <<= (nSlotId
== SID_SAVEASDOC
);
2468 case SID_PRINTDOCDIRECT
:
2469 nVbaEventId
= VBAEventId::WORKBOOK_BEFOREPRINT
;
2473 sal_Bool bSlotExecutable
= sal_True
;
2474 if( nVbaEventId
!= VBAEventId::NO_EVENT
) try
2476 uno::Reference
< XVBAEventProcessor
> xEventProcessor( aDocument
.GetVbaEventProcessor(), uno::UNO_QUERY_THROW
);
2477 xEventProcessor
->processVbaEvent( nVbaEventId
, aArgs
);
2479 catch( util::VetoException
& )
2481 bSlotExecutable
= false;
2483 catch( uno::Exception
& )
2486 return bSlotExecutable
;
2490 sal_uInt16
ScDocShell::PrepareClose( sal_Bool bUI
, sal_Bool bForBrowsing
)
2492 if(SC_MOD()->GetCurRefDlgId()>0)
2494 SfxViewFrame
* pFrame
= SfxViewFrame::GetFirst( this );
2497 SfxViewShell
* p
= pFrame
->GetViewShell();
2498 ScTabViewShell
* pViewSh
= PTR_CAST(ScTabViewShell
,p
);
2501 Window
*pWin
=pViewSh
->GetWindow();
2502 if(pWin
!=NULL
) pWin
->GrabFocus();
2508 if ( aDocument
.IsInLinkUpdate() || aDocument
.IsInInterpreter() )
2510 ErrorMessage(STR_CLOSE_ERROR_LINK
);
2516 // start 'Workbook_BeforeClose' VBA event handler for possible veto
2517 if( !IsInPrepareClose() )
2521 uno::Reference
< script::vba::XVBAEventProcessor
> xVbaEvents( aDocument
.GetVbaEventProcessor(), uno::UNO_SET_THROW
);
2522 uno::Sequence
< uno::Any
> aArgs
;
2523 xVbaEvents
->processVbaEvent( script::vba::VBAEventId::WORKBOOK_BEFORECLOSE
, aArgs
);
2525 catch( util::VetoException
& )
2527 // if event processor throws VetoException, macro has vetoed close
2530 catch( uno::Exception
& )
2536 sal_uInt16 nRet
= SfxObjectShell::PrepareClose( bUI
, bForBrowsing
);
2537 if (nRet
== sal_True
) // sal_True = schliessen
2538 aDocument
.EnableIdle(false); // nicht mehr drin rumpfuschen !!!
2543 void ScDocShell::PrepareReload()
2545 SfxObjectShell::PrepareReload(); // tut nichts?
2547 // Das Disconnect von DDE-Links kann Reschedule ausloesen.
2548 // Wenn die DDE-Links erst im Dokument-dtor geloescht werden, kann beim Reload
2549 // aus diesem Reschedule das DDE-Link-Update fuer das neue Dokument ausgeloest
2550 // werden. Dabei verklemmt sicht dann irgendwas.
2551 // -> Beim Reload die DDE-Links des alten Dokuments vorher disconnecten
2553 aDocument
.DisconnectDdeLinks();
2557 OUString
ScDocShell::GetOwnFilterName()
2559 return OUString(pFilterSc50
);
2562 OUString
ScDocShell::GetHtmlFilterName()
2564 return OUString(pFilterHtml
);
2567 OUString
ScDocShell::GetWebQueryFilterName()
2569 return OUString(pFilterHtmlWebQ
);
2572 OUString
ScDocShell::GetAsciiFilterName()
2574 return OUString(pFilterAscii
);
2577 OUString
ScDocShell::GetLotusFilterName()
2579 return OUString(pFilterLotus
);
2582 OUString
ScDocShell::GetDBaseFilterName()
2584 return OUString(pFilterDBase
);
2587 OUString
ScDocShell::GetDifFilterName()
2589 return OUString(pFilterDif
);
2592 sal_Bool
ScDocShell::HasAutomaticTableName( const OUString
& rFilter
)
2594 // sal_True for those filters that keep the default table name
2595 // (which is language specific)
2597 return rFilter
.equalsAscii( pFilterAscii
)
2598 || rFilter
.equalsAscii( pFilterLotus
)
2599 || rFilter
.equalsAscii( pFilterExcel4
)
2600 || rFilter
.equalsAscii( pFilterEx4Temp
)
2601 || rFilter
.equalsAscii( pFilterDBase
)
2602 || rFilter
.equalsAscii( pFilterDif
)
2603 || rFilter
.equalsAscii( pFilterSylk
)
2604 || rFilter
.equalsAscii( pFilterHtml
)
2605 || rFilter
.equalsAscii( pFilterRtf
);
2608 #if ! ENABLE_TELEPATHY
2609 ScDocFunc
*ScDocShell::CreateDocFunc()
2611 return new ScDocFuncDirect( *this );
2614 ScCollaboration
* ScDocShell::GetCollaboration()
2616 return mpCollaboration
;
2620 ScDocShell::ScDocShell( const ScDocShell
& rShell
) :
2623 SfxObjectShell( rShell
.GetCreateMode() ),
2625 aDocument ( SCDOCMODE_DOCUMENT
, this ),
2626 aDdeTextFmt(OUString("TEXT")),
2627 nPrtToScreenFactor( 1.0 ),
2628 pImpl ( new DocShell_Impl
),
2632 bIsInUndo ( false ),
2633 bDocumentModifiedPending( false ),
2634 bUpdateEnabled ( true ),
2635 nDocumentLock ( 0 ),
2636 nCanUpdate (com::sun::star::document::UpdateDocMode::ACCORDING_TO_CONFIG
),
2637 pOldAutoDBRange ( NULL
),
2638 pDocHelper ( NULL
),
2639 pAutoStyleList ( NULL
),
2640 pPaintLockData ( NULL
),
2641 pSolverSaveData ( NULL
),
2642 pSheetSaveData ( NULL
),
2643 pModificator ( NULL
)
2644 #if ENABLE_TELEPATHY
2645 , mpCollaboration( new ScCollaboration( this ) )
2648 SetPool( &SC_MOD()->GetPool() );
2650 bIsInplace
= rShell
.bIsInplace
;
2652 pDocFunc
= CreateDocFunc();
2654 // SetBaseModel needs exception handling
2655 ScModelObj::CreateAndSet( this );
2657 StartListening(*this);
2658 SfxStyleSheetPool
* pStlPool
= aDocument
.GetStyleSheetPool();
2660 StartListening(*pStlPool
);
2662 GetPageOnFromPageStyleSet( NULL
, 0, bHeaderOn
, bFooterOn
);
2663 SetHelpId( HID_SCSHELL_DOCSH
);
2665 // InitItems und CalcOutputFactor werden jetzt nach bei Load/ConvertFrom/InitNew gerufen
2668 //------------------------------------------------------------------
2670 ScDocShell::ScDocShell( const sal_uInt64 i_nSfxCreationFlags
) :
2671 SfxObjectShell( i_nSfxCreationFlags
),
2672 aDocument ( SCDOCMODE_DOCUMENT
, this ),
2673 aDdeTextFmt(OUString("TEXT")),
2674 nPrtToScreenFactor( 1.0 ),
2675 pImpl ( new DocShell_Impl
),
2679 bIsInUndo ( false ),
2680 bDocumentModifiedPending( false ),
2681 bUpdateEnabled ( true ),
2682 nDocumentLock ( 0 ),
2683 nCanUpdate (com::sun::star::document::UpdateDocMode::ACCORDING_TO_CONFIG
),
2684 pOldAutoDBRange ( NULL
),
2685 pDocHelper ( NULL
),
2686 pAutoStyleList ( NULL
),
2687 pPaintLockData ( NULL
),
2688 pSolverSaveData ( NULL
),
2689 pSheetSaveData ( NULL
),
2690 pModificator ( NULL
)
2691 #if ENABLE_TELEPATHY
2692 , mpCollaboration( new ScCollaboration( this ) )
2695 SetPool( &SC_MOD()->GetPool() );
2697 bIsInplace
= (GetCreateMode() == SFX_CREATE_MODE_EMBEDDED
);
2698 // wird zurueckgesetzt, wenn nicht inplace
2700 pDocFunc
= CreateDocFunc();
2702 // SetBaseModel needs exception handling
2703 ScModelObj::CreateAndSet( this );
2705 StartListening(*this);
2706 SfxStyleSheetPool
* pStlPool
= aDocument
.GetStyleSheetPool();
2708 StartListening(*pStlPool
);
2709 SetHelpId( HID_SCSHELL_DOCSH
);
2711 aDocument
.GetDBCollection()->SetRefreshHandler(
2712 LINK( this, ScDocShell
, RefreshDBDataHdl
) );
2714 // InitItems und CalcOutputFactor werden jetzt nach bei Load/ConvertFrom/InitNew gerufen
2717 //------------------------------------------------------------------
2719 ScDocShell::~ScDocShell()
2721 ResetDrawObjectShell(); // falls der Drawing-Layer noch versucht, darauf zuzugreifen
2723 SfxStyleSheetPool
* pStlPool
= aDocument
.GetStyleSheetPool();
2725 EndListening(*pStlPool
);
2726 EndListening(*this);
2728 delete pAutoStyleList
;
2730 SfxApplication
*pSfxApp
= SFX_APP();
2731 if ( pSfxApp
->GetDdeService() ) // DDE vor Dokument loeschen
2732 pSfxApp
->RemoveDdeTopic( this );
2735 delete aDocument
.mpUndoManager
;
2736 aDocument
.mpUndoManager
= 0;
2739 delete pPaintLockData
;
2741 delete pSolverSaveData
;
2742 delete pSheetSaveData
;
2743 delete pOldAutoDBRange
;
2747 OSL_FAIL("The Modificator should not exist");
2748 delete pModificator
;
2750 #if ENABLE_TELEPATHY
2751 delete mpCollaboration
;
2755 //------------------------------------------------------------------
2757 ::svl::IUndoManager
* ScDocShell::GetUndoManager()
2759 return aDocument
.GetUndoManager();
2762 void ScDocShell::SetModified( sal_Bool bModified
)
2764 if ( SfxObjectShell::IsEnableSetModified() )
2766 SfxObjectShell::SetModified( bModified
);
2767 Broadcast( SfxSimpleHint( SFX_HINT_DOCCHANGED
) );
2772 void ScDocShell::SetDocumentModified( sal_Bool bIsModified
/* = sal_True */ )
2774 // BroadcastUno muss auch mit pPaintLockData sofort passieren
2775 //! auch bei SetDrawModified, wenn Drawing angebunden ist
2776 //! dann eigener Hint???
2778 if ( pPaintLockData
&& bIsModified
)
2780 // #i115009# broadcast BCA_BRDCST_ALWAYS, so a component can read recalculated results
2781 // of RecalcModeAlways formulas (like OFFSET) after modifying cells
2782 aDocument
.Broadcast(ScHint(SC_HINT_DATACHANGED
, BCA_BRDCST_ALWAYS
));
2783 aDocument
.InvalidateTableArea(); // #i105279# needed here
2784 aDocument
.BroadcastUno( SfxSimpleHint( SFX_HINT_DATACHANGED
) );
2786 pPaintLockData
->SetModified(); // spaeter...
2790 SetDrawModified( bIsModified
);
2794 if ( aDocument
.IsAutoCalcShellDisabled() )
2795 SetDocumentModifiedPending( sal_True
);
2798 SetDocumentModifiedPending( false );
2799 aDocument
.InvalidateStyleSheetUsage();
2800 aDocument
.InvalidateTableArea();
2801 aDocument
.InvalidateLastTableOpParams();
2802 aDocument
.Broadcast(ScHint(SC_HINT_DATACHANGED
, BCA_BRDCST_ALWAYS
));
2803 if ( aDocument
.IsForcedFormulaPending() && aDocument
.GetAutoCalc() )
2804 aDocument
.CalcFormulaTree( sal_True
);
2807 // Detective AutoUpdate:
2808 // Update if formulas were modified (DetectiveDirty) or the list contains
2809 // "Trace Error" entries (Trace Error can look completely different
2810 // after changes to non-formula cells).
2812 ScDetOpList
* pList
= aDocument
.GetDetOpList();
2813 if ( pList
&& ( aDocument
.IsDetectiveDirty() || pList
->HasAddError() ) &&
2814 pList
->Count() && !IsInUndo() && SC_MOD()->GetAppOptions().GetDetectiveAuto() )
2816 GetDocFunc().DetectiveRefresh(sal_True
); // sal_True = caused by automatic update
2818 aDocument
.SetDetectiveDirty(false); // always reset, also if not refreshed
2821 // notify UNO objects after BCA_BRDCST_ALWAYS etc.
2822 aDocument
.BroadcastUno( SfxSimpleHint( SFX_HINT_DATACHANGED
) );
2826 // SetDrawModified - ohne Formel-Update
2827 // (Drawing muss auch beim normalen SetDocumentModified upgedated werden,
2828 // z.B. bei Tabelle loeschen etc.)
2830 void ScDocShell::SetDrawModified( sal_Bool bIsModified
/* = sal_True */ )
2832 sal_Bool bUpdate
= ( bIsModified
!= IsModified() );
2834 SetModified( bIsModified
);
2836 SfxBindings
* pBindings
= GetViewBindings();
2841 pBindings
->Invalidate( SID_SAVEDOC
);
2842 pBindings
->Invalidate( SID_DOC_MODIFIED
);
2850 // #i105960# Undo etc used to be volatile.
2851 // They always have to be invalidated, including drawing layer or row height changes
2852 // (but not while pPaintLockData is set).
2853 pBindings
->Invalidate( SID_UNDO
);
2854 pBindings
->Invalidate( SID_REDO
);
2855 pBindings
->Invalidate( SID_REPEAT
);
2858 if ( aDocument
.IsChartListenerCollectionNeedsUpdate() )
2860 aDocument
.UpdateChartListenerCollection();
2861 SFX_APP()->Broadcast(SfxSimpleHint( SC_HINT_DRAW_CHANGED
)); // Navigator
2863 SC_MOD()->AnythingChanged();
2867 void ScDocShell::SetInUndo(bool bSet
)
2873 void ScDocShell::GetDocStat( ScDocStat
& rDocStat
)
2875 SfxPrinter
* pPrinter
= GetPrinter();
2877 aDocument
.GetDocStat( rDocStat
);
2878 rDocStat
.nPageCount
= 0;
2881 for ( SCTAB i
=0; i
<rDocStat
.nTableCount
; i
++ )
2882 rDocStat
.nPageCount
= sal::static_int_cast
<sal_uInt16
>( rDocStat
.nPageCount
+
2883 (sal_uInt16
) ScPrintFunc( this, pPrinter
, i
).GetTotalPages() );
2887 SfxDocumentInfoDialog
* ScDocShell::CreateDocumentInfoDialog(
2888 Window
*pParent
, const SfxItemSet
&rSet
)
2890 SfxDocumentInfoDialog
* pDlg
= new SfxDocumentInfoDialog( pParent
, rSet
);
2891 ScDocShell
* pDocSh
= PTR_CAST(ScDocShell
,SfxObjectShell::Current());
2893 //nur mit Statistik, wenn dieses Doc auch angezeigt wird, nicht
2894 //aus dem Doc-Manager
2896 if( pDocSh
== this )
2898 ScAbstractDialogFactory
* pFact
= ScAbstractDialogFactory::Create();
2899 OSL_ENSURE(pFact
, "ScAbstractFactory create fail!");
2900 ::CreateTabPage ScDocStatPageCreate
= pFact
->GetTabPageCreatorFunc( RID_SCPAGE_STAT
);
2901 OSL_ENSURE(ScDocStatPageCreate
, "Tabpage create fail!");
2902 pDlg
->AddFontTabPage();
2903 pDlg
->AddTabPage( 42,
2904 ScGlobal::GetRscString( STR_DOC_STAT
),
2905 ScDocStatPageCreate
,
2911 Window
* ScDocShell::GetActiveDialogParent()
2913 ScTabViewShell
* pViewSh
= ScTabViewShell::GetActiveViewShell();
2915 return pViewSh
->GetDialogParent();
2917 return Application::GetDefDialogParent();
2920 void ScDocShell::SetSolverSaveData( const ScOptSolverSave
& rData
)
2922 delete pSolverSaveData
;
2923 pSolverSaveData
= new ScOptSolverSave( rData
);
2926 ScSheetSaveData
* ScDocShell::GetSheetSaveData()
2928 if (!pSheetSaveData
)
2929 pSheetSaveData
= new ScSheetSaveData
;
2931 return pSheetSaveData
;
2936 void removeKeysIfExists(Reference
<ui::XAcceleratorConfiguration
>& xScAccel
, const vector
<const awt::KeyEvent
*>& rKeys
)
2938 vector
<const awt::KeyEvent
*>::const_iterator itr
= rKeys
.begin(), itrEnd
= rKeys
.end();
2939 for (; itr
!= itrEnd
; ++itr
)
2941 const awt::KeyEvent
* p
= *itr
;
2947 xScAccel
->removeKeyEvent(*p
);
2949 catch (const container::NoSuchElementException
&) {}
2955 void ScDocShell::ResetKeyBindings( ScOptionsUtil::KeyBindingType eType
)
2957 using namespace ::com::sun::star::ui
;
2959 Reference
<uno::XComponentContext
> xContext
= ::comphelper::getProcessComponentContext();
2963 Reference
<XModuleUIConfigurationManagerSupplier
> xModuleCfgSupplier(
2964 ModuleUIConfigurationManagerSupplier::create(xContext
) );
2966 // Grab the Calc configuration.
2967 Reference
<XUIConfigurationManager
> xConfigMgr
=
2968 xModuleCfgSupplier
->getUIConfigurationManager(
2969 OUString("com.sun.star.sheet.SpreadsheetDocument"));
2971 if (!xConfigMgr
.is())
2975 Reference
<XAcceleratorConfiguration
> xScAccel
= xConfigMgr
->getShortCutManager();
2980 vector
<const awt::KeyEvent
*> aKeys
;
2984 awt::KeyEvent aBackspace
;
2985 aBackspace
.KeyCode
= awt::Key::BACKSPACE
;
2986 aBackspace
.Modifiers
= 0;
2987 aKeys
.push_back(&aBackspace
);
2990 awt::KeyEvent aDelete
;
2991 aDelete
.KeyCode
= awt::Key::DELETE
;
2992 aDelete
.Modifiers
= 0;
2993 aKeys
.push_back(&aDelete
);
2996 awt::KeyEvent aCtrlD
;
2997 aCtrlD
.KeyCode
= awt::Key::D
;
2998 aCtrlD
.Modifiers
= awt::KeyModifier::MOD1
;
2999 aKeys
.push_back(&aCtrlD
);
3002 awt::KeyEvent aAltDown
;
3003 aAltDown
.KeyCode
= awt::Key::DOWN
;
3004 aAltDown
.Modifiers
= awt::KeyModifier::MOD2
;
3005 aKeys
.push_back(&aAltDown
);
3007 // Remove all involved keys first, because swapping commands don't work
3008 // well without doing this.
3009 removeKeysIfExists(xScAccel
, aKeys
);
3014 case ScOptionsUtil::KEY_DEFAULT
:
3015 xScAccel
->setKeyEvent(aDelete
, OUString(".uno:ClearContents"));
3016 xScAccel
->setKeyEvent(aBackspace
, OUString(".uno:Delete"));
3017 xScAccel
->setKeyEvent(aCtrlD
, OUString(".uno:FillDown"));
3018 xScAccel
->setKeyEvent(aAltDown
, OUString(".uno:DataSelect"));
3020 case ScOptionsUtil::KEY_OOO_LEGACY
:
3021 xScAccel
->setKeyEvent(aDelete
, OUString(".uno:Delete"));
3022 xScAccel
->setKeyEvent(aBackspace
, OUString(".uno:ClearContents"));
3023 xScAccel
->setKeyEvent(aCtrlD
, OUString(".uno:DataSelect"));
3032 void ScDocShell::UseSheetSaveEntries()
3036 pSheetSaveData
->UseSaveEntries(); // use positions from saved file for next saving
3038 bool bHasEntries
= false;
3039 SCTAB nTabCount
= aDocument
.GetTableCount();
3041 for (nTab
= 0; nTab
< nTabCount
; ++nTab
)
3042 if (pSheetSaveData
->HasStreamPos(nTab
))
3047 // if no positions were set (for example, export to other format),
3048 // reset all "valid" flags
3050 for (nTab
= 0; nTab
< nTabCount
; ++nTab
)
3051 if (aDocument
.IsStreamValid(nTab
))
3052 aDocument
.SetStreamValid(nTab
, false);
3057 // --- ScDocShellModificator ------------------------------------------
3059 ScDocShellModificator::ScDocShellModificator( ScDocShell
& rDS
)
3062 mpProtector(new ScRefreshTimerProtector(rDS
.GetDocument()->GetRefreshTimerControlAddress()))
3064 ScDocument
* pDoc
= rDocShell
.GetDocument();
3065 bAutoCalcShellDisabled
= pDoc
->IsAutoCalcShellDisabled();
3066 bIdleEnabled
= pDoc
->IsIdleEnabled();
3067 pDoc
->SetAutoCalcShellDisabled( true );
3068 pDoc
->EnableIdle(false);
3072 ScDocShellModificator::~ScDocShellModificator()
3074 ScDocument
* pDoc
= rDocShell
.GetDocument();
3075 pDoc
->SetAutoCalcShellDisabled( bAutoCalcShellDisabled
);
3076 if ( !bAutoCalcShellDisabled
&& rDocShell
.IsDocumentModifiedPending() )
3077 rDocShell
.SetDocumentModified(); // last one shuts off the lights
3078 pDoc
->EnableIdle(bIdleEnabled
);
3082 void ScDocShellModificator::SetDocumentModified()
3084 ScDocument
* pDoc
= rDocShell
.GetDocument();
3085 pDoc
->CellContentModified();
3086 if ( !pDoc
->IsImportingXML() )
3088 // AutoCalcShellDisabled temporaer restaurieren
3089 bool bDisabled
= pDoc
->IsAutoCalcShellDisabled();
3090 pDoc
->SetAutoCalcShellDisabled( bAutoCalcShellDisabled
);
3091 rDocShell
.SetDocumentModified();
3092 pDoc
->SetAutoCalcShellDisabled( bDisabled
);
3096 // uno broadcast is necessary for api to work
3097 // -> must also be done during xml import
3098 pDoc
->BroadcastUno( SfxSimpleHint( SFX_HINT_DATACHANGED
) );
3102 bool ScDocShell::IsChangeRecording() const
3104 ScChangeTrack
* pChangeTrack
= aDocument
.GetChangeTrack();
3105 return pChangeTrack
!= NULL
;
3109 bool ScDocShell::HasChangeRecordProtection() const
3112 ScChangeTrack
* pChangeTrack
= aDocument
.GetChangeTrack();
3114 bRes
= pChangeTrack
->IsProtected();
3119 void ScDocShell::SetChangeRecording( bool bActivate
)
3121 bool bOldChangeRecording
= IsChangeRecording();
3125 aDocument
.StartChangeTracking();
3126 ScChangeViewSettings aChangeViewSet
;
3127 aChangeViewSet
.SetShowChanges(sal_True
);
3128 aDocument
.SetChangeViewSettings(aChangeViewSet
);
3132 aDocument
.EndChangeTracking();
3136 if (bOldChangeRecording
!= IsChangeRecording())
3138 UpdateAcceptChangesDialog();
3139 // Slots invalidieren
3140 SfxBindings
* pBindings
= GetViewBindings();
3142 pBindings
->InvalidateAll(false);
3147 bool ScDocShell::SetProtectionPassword( const OUString
&rNewPassword
)
3150 ScChangeTrack
* pChangeTrack
= aDocument
.GetChangeTrack();
3153 bool bProtected
= pChangeTrack
->IsProtected();
3155 if (!rNewPassword
.isEmpty())
3157 // when password protection is applied change tracking must always be active
3158 SetChangeRecording( true );
3160 ::com::sun::star::uno::Sequence
< sal_Int8
> aProtectionHash
;
3161 SvPasswordHelper::GetHashPassword( aProtectionHash
, rNewPassword
);
3162 pChangeTrack
->SetProtection( aProtectionHash
);
3166 pChangeTrack
->SetProtection( ::com::sun::star::uno::Sequence
< sal_Int8
>() );
3170 if ( bProtected
!= pChangeTrack
->IsProtected() )
3172 UpdateAcceptChangesDialog();
3173 SetDocumentModified();
3181 bool ScDocShell::GetProtectionHash( /*out*/ ::com::sun::star::uno::Sequence
< sal_Int8
> &rPasswordHash
)
3184 ScChangeTrack
* pChangeTrack
= aDocument
.GetChangeTrack();
3185 if (pChangeTrack
&& pChangeTrack
->IsProtected())
3187 rPasswordHash
= pChangeTrack
->GetProtection();
3193 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */