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 pFilterXML
[] = "StarOffice XML (Calc)";
148 static const sal_Char pFilterAscii
[] = "Text - txt - csv (StarCalc)";
149 static const sal_Char pFilterLotus
[] = "Lotus";
150 static const sal_Char pFilterQPro6
[] = "Quattro Pro 6.0";
151 static const sal_Char pFilterExcel4
[] = "MS Excel 4.0";
152 static const sal_Char pFilterEx4Temp
[] = "MS Excel 4.0 Vorlage/Template";
153 static const sal_Char pFilterExcel5
[] = "MS Excel 5.0/95";
154 static const sal_Char pFilterEx5Temp
[] = "MS Excel 5.0/95 Vorlage/Template";
155 static const sal_Char pFilterExcel95
[] = "MS Excel 95";
156 static const sal_Char pFilterEx95Temp
[] = "MS Excel 95 Vorlage/Template";
157 static const sal_Char pFilterExcel97
[] = "MS Excel 97";
158 static const sal_Char pFilterEx97Temp
[] = "MS Excel 97 Vorlage/Template";
159 static const sal_Char pFilterDBase
[] = "dBase";
160 static const sal_Char pFilterDif
[] = "DIF";
161 static const sal_Char pFilterSylk
[] = "SYLK";
162 static const sal_Char pFilterHtml
[] = "HTML (StarCalc)";
163 static const sal_Char pFilterHtmlWebQ
[] = "calc_HTML_WebQuery";
164 static const sal_Char pFilterRtf
[] = "Rich Text Format (StarCalc)";
167 #include "scslots.hxx"
169 SFX_IMPL_INTERFACE(ScDocShell
,SfxObjectShell
)
171 void ScDocShell::InitInterface_Impl()
175 // GlobalName of the current version:
176 SFX_IMPL_OBJECTFACTORY( ScDocShell
, SvGlobalName(SO3_SC_CLASSID
), SfxObjectShellFlags::STD_NORMAL
, "scalc" )
178 TYPEINIT1( ScDocShell
, SfxObjectShell
); // SfxInPlaceObject: No TypeInfo?
180 void ScDocShell::FillClass( SvGlobalName
* pClassName
,
181 SotClipboardFormatId
* pFormat
,
182 OUString
* /* pAppName */,
183 OUString
* pFullTypeName
,
184 OUString
* pShortTypeName
,
185 sal_Int32 nFileFormat
,
186 bool bTemplate
/* = false */) const
188 if ( nFileFormat
== SOFFICE_FILEFORMAT_60
)
190 *pClassName
= SvGlobalName( SO3_SC_CLASSID_60
);
191 *pFormat
= SotClipboardFormatId::STARCALC_60
;
192 *pFullTypeName
= OUString( ScResId( SCSTR_LONG_SCDOC_NAME
) );
193 *pShortTypeName
= OUString( ScResId( SCSTR_SHORT_SCDOC_NAME
) );
195 else if ( nFileFormat
== SOFFICE_FILEFORMAT_8
)
197 *pClassName
= SvGlobalName( SO3_SC_CLASSID_60
);
198 *pFormat
= bTemplate
? SotClipboardFormatId::STARCALC_8_TEMPLATE
: SotClipboardFormatId::STARCALC_8
;
199 *pFullTypeName
= "calc8";
200 *pShortTypeName
= ScResId(SCSTR_SHORT_SCDOC_NAME
).toString();
204 OSL_FAIL("Which version?");
208 std::set
<Color
> ScDocShell::GetDocColors()
210 return aDocument
.GetDocColors();
213 void ScDocShell::DoEnterHandler()
215 ScTabViewShell
* pViewSh
= ScTabViewShell::GetActiveViewShell();
217 if (pViewSh
->GetViewData().GetDocShell() == this)
218 SC_MOD()->InputEnterHandler();
221 SCTAB
ScDocShell::GetSaveTab()
224 ScTabViewShell
* pSh
= GetBestViewShell();
227 const ScMarkData
& rMark
= pSh
->GetViewData().GetMarkData();
228 nTab
= rMark
.GetFirstSelected();
233 HiddenInformation
ScDocShell::GetHiddenInformationState( HiddenInformation nStates
)
235 // get global state like HiddenInformation::DOCUMENTVERSIONS
236 HiddenInformation nState
= SfxObjectShell::GetHiddenInformationState( nStates
);
238 if ( nStates
& HiddenInformation::RECORDEDCHANGES
)
240 if ( aDocument
.GetChangeTrack() && aDocument
.GetChangeTrack()->GetFirst() )
241 nState
|= HiddenInformation::RECORDEDCHANGES
;
243 if ( nStates
& HiddenInformation::NOTES
)
245 SCTAB nTableCount
= aDocument
.GetTableCount();
247 for (SCTAB nTab
= 0; nTab
< nTableCount
&& !bFound
; ++nTab
)
249 if (aDocument
.HasTabNotes(nTab
)) //TODO:
254 nState
|= HiddenInformation::NOTES
;
260 void ScDocShell::BeforeXMLLoading()
262 aDocument
.EnableIdle(false);
264 // prevent unnecessary broadcasts and updates
265 OSL_ENSURE(pModificator
== NULL
, "The Modificator should not exist");
266 pModificator
= new ScDocShellModificator( *this );
268 aDocument
.SetImportingXML( true );
269 aDocument
.EnableExecuteLink( false ); // #i101304# to be safe, prevent nested loading from external references
270 aDocument
.EnableUndo( false );
271 // prevent unnecessary broadcasts and "half way listeners"
272 aDocument
.SetInsertingFromOtherDoc( true );
275 void ScDocShell::AfterXMLLoading(bool bRet
)
277 if (GetCreateMode() != SfxObjectCreateMode::ORGANIZER
)
280 // don't prevent establishing of listeners anymore
281 aDocument
.SetInsertingFromOtherDoc( false );
284 ScChartListenerCollection
* pChartListener
= aDocument
.GetChartListenerCollection();
286 pChartListener
->UpdateDirtyCharts();
288 // #95582#; set the table names of linked tables to the new path
289 SCTAB nTabCount
= aDocument
.GetTableCount();
290 for (SCTAB i
= 0; i
< nTabCount
; ++i
)
292 if (aDocument
.IsLinked( i
))
295 aDocument
.GetName(i
, aName
);
296 OUString aLinkTabName
= aDocument
.GetLinkTab(i
);
297 sal_Int32 nLinkTabNameLength
= aLinkTabName
.getLength();
298 sal_Int32 nNameLength
= aName
.getLength();
299 if (nLinkTabNameLength
< nNameLength
)
302 // remove the quottes on begin and end of the docname and restore the escaped quotes
303 const sal_Unicode
* pNameBuffer
= aName
.getStr();
304 if ( *pNameBuffer
== '\'' && // all docnames have to have a ' character on the first pos
305 ScGlobal::UnicodeStrChr( pNameBuffer
, SC_COMPILER_FILE_TAB_SEP
) )
307 OUStringBuffer aDocURLBuffer
;
308 bool bQuote
= true; // Document name is always quoted
310 while ( bQuote
&& *pNameBuffer
)
312 if ( *pNameBuffer
== '\'' && *(pNameBuffer
-1) != '\\' )
314 else if( !(*pNameBuffer
== '\\' && *(pNameBuffer
+1) == '\'') )
315 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() == SfxObjectCreateMode::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.
475 ScopedVclPtrInstance
<QueryBox
> aBox(
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 std::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() != SfxObjectCreateMode::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( SfxLoadedFlags::ALL
);
602 void ScDocShell::Notify( SfxBroadcaster
&, const SfxHint
& rHint
)
604 const ScTablesHint
* pScHint
= dynamic_cast< const ScTablesHint
* >( &rHint
);
607 if (pScHint
->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] <<= pScHint
->GetTab1();
614 xVbaEvents
->processVbaEvent( script::vba::VBAEventId::WORKBOOK_NEWSHEET
, aArgs
);
616 catch( uno::Exception
& )
622 if ( dynamic_cast<const SfxSimpleHint
*>(&rHint
) ) // Without parameter
624 sal_uLong nSlot
= static_cast<const SfxSimpleHint
&>(rHint
).GetId();
627 case SFX_HINT_TITLECHANGED
:
628 aDocument
.SetName( SfxShell::GetName() );
629 // RegisterNewTargetNames gibts nicht mehr
630 SfxGetpApp()->Broadcast(SfxSimpleHint( SC_HINT_DOCNAME_CHANGED
)); // Navigator
634 else if ( dynamic_cast<const SfxStyleSheetHint
*>(&rHint
) ) // Template changed
635 NotifyStyle( static_cast<const SfxStyleSheetHint
&>(rHint
) );
636 else if ( dynamic_cast<const ScAutoStyleHint
*>(&rHint
) )
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 const ScAutoStyleHint
& rStlHint
= static_cast<const 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 ( dynamic_cast<const SfxEventHint
*>(&rHint
) )
656 sal_uLong nEventId
= static_cast<const 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 ScopedVclPtrInstance
<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 LockFileEntry aData
= aLockFile
.GetLockData();
797 if ( !aData
[LockFileComponent::OOOUSERNAME
].isEmpty() )
799 aUserName
= aData
[LockFileComponent::OOOUSERNAME
];
801 else if ( !aData
[LockFileComponent::SYSUSERNAME
].isEmpty() )
803 aUserName
= aData
[LockFileComponent::SYSUSERNAME
];
806 catch ( uno::Exception
& )
808 bNoLockAccess
= true;
813 // TODO/LATER: in future an error regarding impossibility to open file for writing could be shown
814 ErrorHandler::HandleError( ERRCODE_IO_GENERAL
);
818 OUString
aMessage( ScGlobal::GetRscString( STR_FILE_LOCKED_SAVE_LATER
) );
819 aMessage
= aMessage
.replaceFirst( "%1", aUserName
);
821 ScopedVclPtrInstance
< WarningBox
> aBox( GetActiveDialogParent(), WinBits( WB_RETRY_CANCEL
| WB_DEF_RETRY
), aMessage
);
822 if ( aBox
->Execute() == RET_RETRY
)
830 // merge changes from shared file into temp file
831 bool bSaveToShared
= false;
832 if ( pSharedDocShell
)
834 bSaveToShared
= MergeSharedDocument( pSharedDocShell
);
838 xCloseable
->close( sal_True
);
840 // TODO: keep file lock on shared file
842 // store to shared file
845 bool bChangedViewSettings
= false;
846 ScChangeViewSettings
* pChangeViewSet
= aDocument
.GetChangeViewSettings();
847 if ( pChangeViewSet
&& pChangeViewSet
->ShowChanges() )
849 pChangeViewSet
->SetShowChanges( false );
850 pChangeViewSet
->SetShowAccepted( false );
851 aDocument
.SetChangeViewSettings( *pChangeViewSet
);
852 bChangedViewSettings
= true;
855 uno::Reference
< frame::XStorable
> xStor( GetModel(), uno::UNO_QUERY_THROW
);
856 // TODO/LATER: More entries from the MediaDescriptor might be interesting for the merge
857 uno::Sequence
< beans::PropertyValue
> aValues(1);
858 aValues
[0].Name
= "FilterName";
859 aValues
[0].Value
<<= OUString( GetMedium()->GetFilter()->GetFilterName() );
861 SFX_ITEMSET_ARG( GetMedium()->GetItemSet(), pPasswordItem
, SfxStringItem
, SID_PASSWORD
, false);
862 if ( pPasswordItem
&& !pPasswordItem
->GetValue().isEmpty() )
864 aValues
.realloc( 2 );
865 aValues
[1].Name
= "Password";
866 aValues
[1].Value
<<= pPasswordItem
->GetValue();
869 SC_MOD()->SetInSharedDocSaving( true );
870 xStor
->storeToURL( GetSharedFileURL(), aValues
);
871 SC_MOD()->SetInSharedDocSaving( false );
873 if ( bChangedViewSettings
)
875 pChangeViewSet
->SetShowChanges( true );
876 pChangeViewSet
->SetShowAccepted( true );
877 aDocument
.SetChangeViewSettings( *pChangeViewSet
);
882 GetUndoManager()->Clear();
887 xCloseable
->close( sal_True
);
889 if ( bEntriesNotAccessible
)
891 // TODO/LATER: in future an error regarding impossibility to write to share control file could be shown
892 ErrorHandler::HandleError( ERRCODE_IO_GENERAL
);
896 ScopedVclPtrInstance
<WarningBox
> aBox( GetActiveDialogParent(), WinBits( WB_OK
),
897 ScGlobal::GetRscString( STR_DOC_NOLONGERSHARED
) );
900 SfxBindings
* pBindings
= GetViewBindings();
903 pBindings
->ExecuteSynchron( SID_SAVEASDOC
);
908 catch ( uno::Exception
& )
910 OSL_FAIL( "SFX_EVENT_SAVEDOC: caught exception\n" );
911 SC_MOD()->SetInSharedDocSaving( false );
915 uno::Reference
< util::XCloseable
> xClose( xModel
, uno::UNO_QUERY_THROW
);
916 xClose
->close( sal_True
);
918 catch ( uno::Exception
& )
925 SetError( ERRCODE_IO_ABORT
, OUString( OSL_LOG_PREFIX
) ); // this error code will produce no error message, but will break the further saving process
930 pSheetSaveData
->SetInSupportedSave(true);
933 case SFX_EVENT_SAVEASDOC
:
935 if ( GetDocument().GetExternalRefManager()->containsUnsavedReferences() )
937 ScopedVclPtrInstance
<WarningBox
> aBox( GetActiveDialogParent(), WinBits( WB_YES_NO
),
938 ScGlobal::GetRscString( STR_UNSAVED_EXT_REF
) );
940 if( RET_NO
== aBox
->Execute())
942 SetError( ERRCODE_IO_ABORT
, OUString( OSL_LOG_PREFIX
) ); // this error code will produce no error message, but will break the further saving process
946 case SFX_EVENT_SAVETODOC
:
947 // #i108978# If no event is sent before saving, there will also be no "...DONE" event,
948 // and SAVE/SAVEAS can't be distinguished from SAVETO. So stream copying is only enabled
949 // if there is a SAVE/SAVEAS/SAVETO event first.
951 pSheetSaveData
->SetInSupportedSave(true);
953 case SFX_EVENT_SAVEDOCDONE
:
954 case SFX_EVENT_SAVEASDOCDONE
:
956 // new positions are used after "save" and "save as", but not "save to"
957 UseSheetSaveEntries(); // use positions from saved file for next saving
959 case SFX_EVENT_SAVETODOCDONE
:
960 // only reset the flag, don't use the new positions
962 pSheetSaveData
->SetInSupportedSave(false);
972 // Load contents for organizer
973 bool ScDocShell::LoadFrom( SfxMedium
& rMedium
)
975 LoadMediumGuard
aLoadGuard(&aDocument
);
976 ScRefreshTimerProtector
aProt( aDocument
.GetRefreshTimerControlAddress() );
978 WaitObject
aWait( GetActiveDialogParent() );
984 SFX_ITEMSET_ARG( rMedium
.GetItemSet(), pUpdateDocItem
, SfxUInt16Item
, SID_UPDATEDOCMODE
, false);
985 nCanUpdate
= pUpdateDocItem
? pUpdateDocItem
->GetValue() : com::sun::star::document::UpdateDocMode::NO_UPDATE
;
988 // until loading/saving only the styles in XML is implemented,
989 // load the whole file
990 bRet
= LoadXML( &rMedium
, NULL
);
993 SfxObjectShell::LoadFrom( rMedium
);
998 static void lcl_parseHtmlFilterOption(const OUString
& rOption
, LanguageType
& rLang
, bool& rDateConvert
)
1000 OUStringBuffer aBuf
;
1001 std::vector
< OUString
> aTokens
;
1002 sal_Int32 n
= rOption
.getLength();
1003 const sal_Unicode
* p
= rOption
.getStr();
1004 for (sal_Int32 i
= 0; i
< n
; ++i
)
1006 const sal_Unicode c
= p
[i
];
1009 if (!aBuf
.isEmpty())
1010 aTokens
.push_back( aBuf
.makeStringAndClear() );
1016 if (!aBuf
.isEmpty())
1017 aTokens
.push_back( aBuf
.makeStringAndClear() );
1019 rLang
= LanguageType( 0 );
1020 rDateConvert
= false;
1022 if (aTokens
.size() > 0)
1023 rLang
= static_cast<LanguageType
>(aTokens
[0].toInt32());
1024 if (aTokens
.size() > 1)
1025 rDateConvert
= static_cast<bool>(aTokens
[1].toInt32());
1028 bool ScDocShell::ConvertFrom( SfxMedium
& rMedium
)
1030 LoadMediumGuard
aLoadGuard(&aDocument
);
1032 bool bRet
= false; // sal_False means user quit!
1033 // On error: Set error at stream
1035 ScRefreshTimerProtector
aProt( aDocument
.GetRefreshTimerControlAddress() );
1037 GetUndoManager()->Clear();
1039 // Set optimal col width after import?
1040 bool bSetColWidths
= false;
1041 bool bSetSimpleTextColWidths
= false;
1042 ScColWidthParam aColWidthParam
[MAXCOLCOUNT
];
1043 ScRange aColWidthRange
;
1044 // Set optimal row height after import?
1045 bool bSetRowHeights
= false;
1047 vector
<ScDocRowHeightUpdater::TabRanges
> aRecalcRowRangesArray
;
1049 // All filters need the complete file in one piece (not asynchronously)
1050 // So make sure that we transfer the whole file with CreateFileStream
1051 rMedium
.GetPhysicalName(); //! Call CreateFileStream directly, if available
1053 SFX_ITEMSET_ARG( rMedium
.GetItemSet(), pUpdateDocItem
, SfxUInt16Item
, SID_UPDATEDOCMODE
, false);
1054 nCanUpdate
= pUpdateDocItem
? pUpdateDocItem
->GetValue() : com::sun::star::document::UpdateDocMode::NO_UPDATE
;
1056 const SfxFilter
* pFilter
= rMedium
.GetFilter();
1059 OUString aFltName
= pFilter
->GetFilterName();
1061 bool bCalc3
= aFltName
== "StarCalc 3.0";
1062 bool bCalc4
= aFltName
== "StarCalc 4.0";
1063 if (!bCalc3
&& !bCalc4
)
1064 aDocument
.SetInsertingFromOtherDoc( true );
1066 if (aFltName
== pFilterXML
)
1067 bRet
= LoadXML( &rMedium
, NULL
);
1068 else if (aFltName
== "StarCalc 1.0")
1070 SvStream
* pStream
= rMedium
.GetInStream();
1073 FltError eError
= ScFormatFilter::Get().ScImportStarCalc10( *pStream
, &aDocument
);
1074 if (eError
!= eERR_OK
)
1077 SetError(eError
, OUString( OSL_LOG_PREFIX
));
1083 else if (aFltName
== pFilterLotus
)
1086 SfxItemSet
* pSet
= rMedium
.GetItemSet();
1087 const SfxPoolItem
* pItem
;
1088 if ( pSet
&& SfxItemState::SET
==
1089 pSet
->GetItemState( SID_FILE_FILTEROPTIONS
, true, &pItem
) )
1091 sItStr
= static_cast<const SfxStringItem
*>(pItem
)->GetValue();
1094 if (sItStr
.isEmpty())
1096 // default for lotus import (from API without options):
1098 sItStr
= ScGlobal::GetCharsetString( RTL_TEXTENCODING_IBM_437
);
1101 FltError eError
= ScFormatFilter::Get().ScImportLotus123( rMedium
, &aDocument
,
1102 ScGlobal::GetCharsetValue(sItStr
));
1103 if (eError
!= eERR_OK
)
1106 SetError(eError
, OUString( OSL_LOG_PREFIX
));
1108 if( ( eError
& ERRCODE_WARNING_MASK
) == ERRCODE_WARNING_MASK
)
1113 bSetColWidths
= true;
1114 bSetRowHeights
= true;
1116 else if ( aFltName
== pFilterExcel4
|| aFltName
== pFilterExcel5
||
1117 aFltName
== pFilterExcel95
|| aFltName
== pFilterExcel97
||
1118 aFltName
== pFilterEx4Temp
|| aFltName
== pFilterEx5Temp
||
1119 aFltName
== pFilterEx95Temp
|| aFltName
== pFilterEx97Temp
)
1121 EXCIMPFORMAT eFormat
= EIF_AUTO
;
1122 if ( aFltName
== pFilterExcel4
|| aFltName
== pFilterEx4Temp
)
1123 eFormat
= EIF_BIFF_LE4
;
1124 else if ( aFltName
== pFilterExcel5
|| aFltName
== pFilterExcel95
||
1125 aFltName
== pFilterEx5Temp
|| aFltName
== pFilterEx95Temp
)
1126 eFormat
= EIF_BIFF5
;
1127 else if ( aFltName
== pFilterExcel97
|| aFltName
== pFilterEx97Temp
)
1128 eFormat
= EIF_BIFF8
;
1130 MakeDrawLayer(); //! In the filter
1131 CalcOutputFactor(); // prepare update of row height
1132 FltError eError
= ScFormatFilter::Get().ScImportExcel( rMedium
, &aDocument
, eFormat
);
1133 aDocument
.UpdateFontCharSet();
1134 if ( aDocument
.IsChartListenerCollectionNeedsUpdate() )
1135 aDocument
.UpdateChartListenerCollection(); //! For all imports?
1137 // all graphics objects must have names
1138 aDocument
.EnsureGraphicNames();
1140 if (eError
== SCWARN_IMPORT_RANGE_OVERFLOW
)
1143 SetError(eError
, OUString( OSL_LOG_PREFIX
));
1146 else if (eError
!= eERR_OK
)
1149 SetError(eError
, OUString( OSL_LOG_PREFIX
));
1154 else if (aFltName
== pFilterAscii
)
1156 SfxItemSet
* pSet
= rMedium
.GetItemSet();
1157 const SfxPoolItem
* pItem
;
1158 ScAsciiOptions aOptions
;
1159 bool bOptInit
= false;
1161 if ( pSet
&& SfxItemState::SET
==
1162 pSet
->GetItemState( SID_FILE_FILTEROPTIONS
, true, &pItem
) )
1164 aOptions
.ReadFromString( static_cast<const SfxStringItem
*>(pItem
)->GetValue() );
1170 // default for ascii import (from API without options):
1171 // ISO8859-1/MS_1252 encoding, comma, double quotes
1173 aOptions
.SetCharSet( RTL_TEXTENCODING_MS_1252
);
1174 aOptions
.SetFieldSeps( OUString(',') );
1175 aOptions
.SetTextSep( '"' );
1178 FltError eError
= eERR_OK
;
1179 bool bOverflowRow
, bOverflowCol
, bOverflowCell
;
1180 bOverflowRow
= bOverflowCol
= bOverflowCell
= false;
1182 if( ! rMedium
.IsStorage() )
1184 ScImportExport
aImpEx( &aDocument
);
1185 aImpEx
.SetExtOptions( aOptions
);
1187 SvStream
* pInStream
= rMedium
.GetInStream();
1190 pInStream
->SetStreamCharSet( aOptions
.GetCharSet() );
1191 pInStream
->Seek( 0 );
1192 bRet
= aImpEx
.ImportStream( *pInStream
, rMedium
.GetBaseURL() );
1193 eError
= bRet
? eERR_OK
: SCERR_IMPORT_CONNECT
;
1194 aDocument
.StartAllListeners();
1195 sc::SetFormulaDirtyContext aCxt
;
1196 aDocument
.SetAllFormulasDirty(aCxt
);
1197 INetURLObject
aURLObjForDefaultNameSheetName(rMedium
.GetName());
1198 aDocument
.RenameTab(0,aURLObjForDefaultNameSheetName
.GetBase());
1199 bOverflowRow
= aImpEx
.IsOverflowRow();
1200 bOverflowCol
= aImpEx
.IsOverflowCol();
1201 bOverflowCell
= aImpEx
.IsOverflowCell();
1205 OSL_FAIL( "No Stream" );
1209 if (eError
!= eERR_OK
)
1212 SetError(eError
, OUString( OSL_LOG_PREFIX
));
1214 else if (!GetError() && (bOverflowRow
|| bOverflowCol
|| bOverflowCell
))
1216 // precedence: row, column, cell
1217 FltError nWarn
= (bOverflowRow
? SCWARN_IMPORT_ROW_OVERFLOW
:
1218 (bOverflowCol
? SCWARN_IMPORT_COLUMN_OVERFLOW
:
1219 SCWARN_IMPORT_CELL_OVERFLOW
));
1220 SetError( nWarn
, OUString( OSL_LOG_PREFIX
));
1222 bSetColWidths
= true;
1223 bSetSimpleTextColWidths
= true;
1225 else if (aFltName
== pFilterDBase
)
1228 SfxItemSet
* pSet
= rMedium
.GetItemSet();
1229 const SfxPoolItem
* pItem
;
1230 if ( pSet
&& SfxItemState::SET
==
1231 pSet
->GetItemState( SID_FILE_FILTEROPTIONS
, true, &pItem
) )
1233 sItStr
= static_cast<const SfxStringItem
*>(pItem
)->GetValue();
1236 if (sItStr
.isEmpty())
1238 // default for dBase import (from API without options):
1241 sItStr
= ScGlobal::GetCharsetString( RTL_TEXTENCODING_IBM_850
);
1244 ScDocRowHeightUpdater::TabRanges
aRecalcRanges(0);
1245 sal_uLong eError
= DBaseImport( rMedium
.GetPhysicalName(),
1246 ScGlobal::GetCharsetValue(sItStr
), aColWidthParam
, *aRecalcRanges
.mpRanges
);
1247 aRecalcRowRangesArray
.push_back(aRecalcRanges
);
1249 if (eError
!= eERR_OK
)
1252 SetError(eError
, OUString( OSL_LOG_PREFIX
));
1253 bRet
= ( eError
== SCWARN_IMPORT_RANGE_OVERFLOW
);
1258 aColWidthRange
.aStart
.SetRow( 1 ); // Except for the column header
1259 bSetColWidths
= true;
1260 bSetSimpleTextColWidths
= true;
1262 else if (aFltName
== pFilterDif
)
1264 SvStream
* pStream
= rMedium
.GetInStream();
1269 SfxItemSet
* pSet
= rMedium
.GetItemSet();
1270 const SfxPoolItem
* pItem
;
1271 if ( pSet
&& SfxItemState::SET
==
1272 pSet
->GetItemState( SID_FILE_FILTEROPTIONS
, true, &pItem
) )
1274 sItStr
= static_cast<const SfxStringItem
*>(pItem
)->GetValue();
1277 if (sItStr
.isEmpty())
1279 // default for DIF import (from API without options):
1280 // ISO8859-1/MS_1252 encoding
1282 sItStr
= ScGlobal::GetCharsetString( RTL_TEXTENCODING_MS_1252
);
1285 eError
= ScFormatFilter::Get().ScImportDif( *pStream
, &aDocument
, ScAddress(0,0,0),
1286 ScGlobal::GetCharsetValue(sItStr
));
1287 if (eError
!= eERR_OK
)
1290 SetError(eError
, OUString( OSL_LOG_PREFIX
));
1292 if( ( eError
& ERRCODE_WARNING_MASK
) == ERRCODE_WARNING_MASK
)
1298 bSetColWidths
= true;
1299 bSetSimpleTextColWidths
= true;
1300 bSetRowHeights
= true;
1302 else if (aFltName
== pFilterSylk
)
1304 FltError eError
= SCERR_IMPORT_UNKNOWN
;
1305 if( !rMedium
.IsStorage() )
1307 ScImportExport
aImpEx( &aDocument
);
1309 SvStream
* pInStream
= rMedium
.GetInStream();
1312 pInStream
->Seek( 0 );
1313 bRet
= aImpEx
.ImportStream( *pInStream
, rMedium
.GetBaseURL(), SotClipboardFormatId::SYLK
);
1314 eError
= bRet
? eERR_OK
: SCERR_IMPORT_UNKNOWN
;
1315 aDocument
.StartAllListeners();
1316 sc::SetFormulaDirtyContext aCxt
;
1317 aDocument
.SetAllFormulasDirty(aCxt
);
1321 OSL_FAIL( "No Stream" );
1325 if ( eError
!= eERR_OK
&& !GetError() )
1326 SetError(eError
, OUString( OSL_LOG_PREFIX
));
1327 bSetColWidths
= true;
1328 bSetSimpleTextColWidths
= true;
1329 bSetRowHeights
= true;
1331 else if (aFltName
== pFilterQPro6
)
1333 FltError eError
= ScFormatFilter::Get().ScImportQuattroPro( rMedium
, &aDocument
);
1334 if (eError
!= eERR_OK
)
1337 SetError( eError
, OUString( OSL_LOG_PREFIX
) );
1338 if( ( eError
& ERRCODE_WARNING_MASK
) == ERRCODE_WARNING_MASK
)
1343 // TODO: Filter should set column widths. Not doing it here, it may
1344 // result in very narrow or wide columns, depending on content.
1345 // Setting row heights makes cells with font size attribution or
1346 // wrapping enabled look nicer..
1347 bSetRowHeights
= true;
1349 else if (aFltName
== pFilterRtf
)
1351 FltError eError
= SCERR_IMPORT_UNKNOWN
;
1352 if( !rMedium
.IsStorage() )
1354 SvStream
* pInStream
= rMedium
.GetInStream();
1357 pInStream
->Seek( 0 );
1359 eError
= ScFormatFilter::Get().ScImportRTF( *pInStream
, rMedium
.GetBaseURL(), &aDocument
, aRange
);
1360 if (eError
!= eERR_OK
)
1363 SetError(eError
, OUString( OSL_LOG_PREFIX
));
1365 if( ( eError
& ERRCODE_WARNING_MASK
) == ERRCODE_WARNING_MASK
)
1370 aDocument
.StartAllListeners();
1371 sc::SetFormulaDirtyContext aCxt
;
1372 aDocument
.SetAllFormulasDirty(aCxt
);
1373 bSetColWidths
= true;
1374 bSetRowHeights
= true;
1378 OSL_FAIL( "No Stream" );
1382 if ( eError
!= eERR_OK
&& !GetError() )
1383 SetError(eError
, OUString( OSL_LOG_PREFIX
));
1385 else if (aFltName
== pFilterHtml
|| aFltName
== pFilterHtmlWebQ
)
1387 FltError eError
= SCERR_IMPORT_UNKNOWN
;
1388 bool bWebQuery
= aFltName
== pFilterHtmlWebQ
;
1389 if( !rMedium
.IsStorage() )
1391 SvStream
* pInStream
= rMedium
.GetInStream();
1394 LanguageType eLang
= LANGUAGE_SYSTEM
;
1395 bool bDateConvert
= false;
1396 SfxItemSet
* pSet
= rMedium
.GetItemSet();
1397 const SfxPoolItem
* pItem
;
1398 if ( pSet
&& SfxItemState::SET
==
1399 pSet
->GetItemState( SID_FILE_FILTEROPTIONS
, true, &pItem
) )
1401 OUString aFilterOption
= (static_cast<const SfxStringItem
*>(pItem
))->GetValue();
1402 lcl_parseHtmlFilterOption(aFilterOption
, eLang
, bDateConvert
);
1405 pInStream
->Seek( 0 );
1407 // HTML does its own ColWidth/RowHeight
1409 SvNumberFormatter
aNumFormatter( comphelper::getProcessComponentContext(), eLang
);
1410 eError
= ScFormatFilter::Get().ScImportHTML( *pInStream
, rMedium
.GetBaseURL(), &aDocument
, aRange
,
1411 GetOutputFactor(), !bWebQuery
, &aNumFormatter
, bDateConvert
);
1412 if (eError
!= eERR_OK
)
1415 SetError(eError
, OUString( OSL_LOG_PREFIX
));
1417 if( ( eError
& ERRCODE_WARNING_MASK
) == ERRCODE_WARNING_MASK
)
1422 aDocument
.StartAllListeners();
1424 sc::SetFormulaDirtyContext aCxt
;
1425 aDocument
.SetAllFormulasDirty(aCxt
);
1429 OSL_FAIL( "No Stream" );
1433 if ( eError
!= eERR_OK
&& !GetError() )
1434 SetError(eError
, OUString( OSL_LOG_PREFIX
));
1439 SetError(SCERR_IMPORT_NI
, OUString( OSL_LOG_PREFIX
));
1443 aDocument
.SetInsertingFromOtherDoc( false );
1447 OSL_FAIL("No Filter in ConvertFrom");
1452 if ( bRet
&& (bSetColWidths
|| bSetRowHeights
) )
1453 { // Adjust column width/row height; base 100% zoom
1454 Fraction
aZoom( 1, 1 );
1455 double nPPTX
= ScGlobal::nScreenPPTX
* (double) aZoom
/ GetOutputFactor(); // Factor is printer display ratio
1456 double nPPTY
= ScGlobal::nScreenPPTY
* (double) aZoom
;
1457 ScopedVclPtrInstance
< VirtualDevice
> pVirtDev
;
1458 // all sheets (for Excel import)
1459 SCTAB nTabCount
= aDocument
.GetTableCount();
1460 for (SCTAB nTab
=0; nTab
<nTabCount
; nTab
++)
1464 aDocument
.GetCellArea( nTab
, nEndCol
, nEndRow
);
1465 aColWidthRange
.aEnd
.SetCol( nEndCol
);
1466 aColWidthRange
.aEnd
.SetRow( nEndRow
);
1468 aMark
.SetMarkArea( aColWidthRange
);
1469 aMark
.MarkToMulti();
1471 // Order is important: First width, then height
1472 if ( bSetColWidths
)
1474 for ( SCCOL nCol
=0; nCol
<= nEndCol
; nCol
++ )
1476 if (!bSetSimpleTextColWidths
)
1477 aColWidthParam
[nCol
].mbSimpleText
= false;
1479 sal_uInt16 nWidth
= aDocument
.GetOptimalColWidth(
1480 nCol
, nTab
, pVirtDev
, nPPTX
, nPPTY
, aZoom
, aZoom
, false, &aMark
,
1481 &aColWidthParam
[nCol
] );
1482 aDocument
.SetColWidth( nCol
, nTab
,
1483 nWidth
+ (sal_uInt16
)ScGlobal::nLastColWidthExtra
);
1490 // Update all rows in all tables.
1491 ScSizeDeviceProvider
aProv(this);
1492 ScDocRowHeightUpdater
aUpdater(aDocument
, aProv
.GetDevice(), aProv
.GetPPTX(), aProv
.GetPPTY(), NULL
);
1495 else if (!aRecalcRowRangesArray
.empty())
1497 // Update only specified row ranges for better performance.
1498 ScSizeDeviceProvider
aProv(this);
1499 ScDocRowHeightUpdater
aUpdater(aDocument
, aProv
.GetDevice(), aProv
.GetPPTX(), aProv
.GetPPTY(), &aRecalcRowRangesArray
);
1503 FinishedLoading( SfxLoadedFlags::ALL
);
1505 // invalidate eventually temporary table areas
1507 aDocument
.InvalidateTableArea();
1514 bool ScDocShell::LoadExternal( SfxMedium
& rMed
)
1516 const SfxFilter
* pFilter
= rMed
.GetFilter();
1520 if (pFilter
->GetProviderName() == "orcus")
1522 ScOrcusFilters
* pOrcus
= ScFormatFilter::Get().GetOrcusFilters();
1526 const OUString
& rFilterName
= pFilter
->GetName();
1527 if (rFilterName
== "gnumeric")
1529 if (!pOrcus
->importGnumeric(aDocument
, rMed
))
1532 else if (rFilterName
== "csv")
1534 if (!pOrcus
->importCSV(aDocument
, rMed
))
1537 else if (rFilterName
== "xlsx")
1539 if (!pOrcus
->importXLSX(aDocument
, rMed
))
1542 else if (rFilterName
== "ods")
1544 if (!pOrcus
->importODS(aDocument
, rMed
))
1548 FinishedLoading(SfxLoadedFlags::ALL
);
1555 ScDocShell::PrepareSaveGuard::PrepareSaveGuard( ScDocShell
& rDocShell
)
1556 : mrDocShell( rDocShell
)
1558 // DoEnterHandler not here (because of AutoSave), is in ExecuteSave.
1560 ScChartListenerCollection
* pCharts
= mrDocShell
.aDocument
.GetChartListenerCollection();
1562 pCharts
->UpdateDirtyCharts(); // Charts to be updated.
1563 mrDocShell
.aDocument
.StopTemporaryChartLock();
1564 if (mrDocShell
.pAutoStyleList
)
1565 mrDocShell
.pAutoStyleList
->ExecuteAllNow(); // Execute template timeouts now.
1566 if (mrDocShell
.aDocument
.HasExternalRefManager())
1568 ScExternalRefManager
* pRefMgr
= mrDocShell
.aDocument
.GetExternalRefManager();
1569 if (pRefMgr
&& pRefMgr
->hasExternalData())
1571 pRefMgr
->setAllCacheTableReferencedStati( false);
1572 mrDocShell
.aDocument
.MarkUsedExternalReferences(); // Mark tables of external references to be written.
1575 if (mrDocShell
.GetCreateMode()== SfxObjectCreateMode::STANDARD
)
1576 mrDocShell
.SfxObjectShell::SetVisArea( Rectangle() ); // "Normally" worked on => no VisArea.
1579 ScDocShell::PrepareSaveGuard::~PrepareSaveGuard()
1581 if (mrDocShell
.aDocument
.HasExternalRefManager())
1583 ScExternalRefManager
* pRefMgr
= mrDocShell
.aDocument
.GetExternalRefManager();
1584 if (pRefMgr
&& pRefMgr
->hasExternalData())
1586 // Prevent accidental data loss due to lack of knowledge.
1587 pRefMgr
->setAllCacheTableReferencedStati( true);
1592 bool ScDocShell::Save()
1594 ScRefreshTimerProtector
aProt( aDocument
.GetRefreshTimerControlAddress() );
1596 PrepareSaveGuard
aPrepareGuard( *this);
1598 SfxViewFrame
* pFrame1
= SfxViewFrame::GetFirst( this );
1601 vcl::Window
* pWindow
= &pFrame1
->GetWindow();
1604 vcl::Window
* pSysWin
= pWindow
->GetSystemWindow();
1607 pSysWin
->SetAccessibleName(OUString());
1611 // wait cursor is handled with progress bar
1612 bool bRet
= SfxObjectShell::Save();
1614 bRet
= SaveXML( GetMedium(), NULL
);
1621 * Remove the file name from the full path, to keep only the directory path.
1623 void popFileName(OUString
& rPath
)
1625 if (!rPath
.isEmpty())
1627 INetURLObject
aURLObj(rPath
);
1628 aURLObj
.removeSegment();
1629 rPath
= aURLObj
.GetMainURL(INetURLObject::NO_DECODE
);
1635 bool ScDocShell::SaveAs( SfxMedium
& rMedium
)
1637 OUString aCurPath
; // empty for new document that hasn't been saved.
1638 const SfxMedium
* pCurMedium
= GetMedium();
1641 aCurPath
= pCurMedium
->GetName();
1642 popFileName(aCurPath
);
1645 if (!aCurPath
.isEmpty())
1647 // current document has a path -> not a brand-new document.
1648 OUString aNewPath
= rMedium
.GetName();
1649 popFileName(aNewPath
);
1650 OUString aRel
= URIHelper::simpleNormalizedMakeRelative(aCurPath
, aNewPath
);
1651 if (!aRel
.isEmpty())
1653 // Directory path will change before and after the save.
1654 aDocument
.InvalidateStreamOnSave();
1658 ScTabViewShell
* pViewShell
= GetBestViewShell();
1659 bool bNeedsRehash
= ScPassHashHelper::needsPassHashRegen(aDocument
, PASSHASH_SHA1
);
1661 // legacy xls hash double-hashed by SHA1 is also supported.
1662 bNeedsRehash
= ScPassHashHelper::needsPassHashRegen(aDocument
, PASSHASH_XL
, PASSHASH_SHA1
);
1664 if (pViewShell
&& bNeedsRehash
)
1666 if (!pViewShell
->ExecuteRetypePassDlg(PASSHASH_SHA1
))
1667 // password re-type cancelled. Don't save the document.
1671 ScRefreshTimerProtector
aProt( aDocument
.GetRefreshTimerControlAddress() );
1673 PrepareSaveGuard
aPrepareGuard( *this);
1675 OUString aFltName
= rMedium
.GetFilter()->GetFilterName();
1676 bool bChartExport
= aFltName
.indexOf("chart8") != -1;
1678 // wait cursor is handled with progress bar
1682 bRet
= SfxObjectShell::SaveAs( rMedium
);
1684 bRet
= SaveXML( &rMedium
, NULL
);
1688 bRet
= SaveCurrentChart( rMedium
);
1694 bool ScDocShell::IsInformationLost()
1696 //FIXME: If we have time build a correct own way how to handle this
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
);
1714 void lcl_ScDocShell_GetFixedWidthString( OUString
& rStr
, const ScDocument
& rDoc
,
1715 SCTAB nTab
, SCCOL nCol
, bool bValue
, SvxCellHorJustify eHorJust
)
1717 OUString aString
= rStr
;
1718 sal_Int32 nLen
= lcl_ScDocShell_GetColWidthInChars(
1719 rDoc
.GetColWidth( nCol
, nTab
) );
1720 //If the text won't fit in the column
1721 if ( nLen
< aString
.getLength() )
1723 OUStringBuffer aReplacement
;
1725 aReplacement
.append("###");
1727 aReplacement
.append(aString
);
1728 //truncate to the number of characters that should fit, even in the
1729 //bValue case nLen might be < len ###
1730 aString
= comphelper::string::truncateToLength(aReplacement
, nLen
).makeStringAndClear();
1732 if ( nLen
> aString
.getLength() )
1734 if ( bValue
&& eHorJust
== SVX_HOR_JUSTIFY_STANDARD
)
1735 eHorJust
= SVX_HOR_JUSTIFY_RIGHT
;
1736 sal_Int32 nBlanks
= nLen
- aString
.getLength();
1739 case SVX_HOR_JUSTIFY_RIGHT
:
1741 OUStringBuffer aTmp
;
1742 aTmp
= comphelper::string::padToLength( aTmp
, nBlanks
, ' ' );
1743 aString
= aTmp
.append(aString
).makeStringAndClear();
1746 case SVX_HOR_JUSTIFY_CENTER
:
1748 sal_Int32 nLeftPad
= nBlanks
/ 2;
1749 OUStringBuffer aTmp
;
1750 comphelper::string::padToLength( aTmp
, nLeftPad
, ' ' );
1751 aTmp
.append(aString
);
1752 comphelper::string::padToLength( aTmp
, nLen
, ' ' );
1753 aString
= aTmp
.makeStringAndClear();
1758 OUStringBuffer
aTmp(aString
);
1759 comphelper::string::padToLength( aTmp
, nLen
, ' ' );
1760 aString
= aTmp
.makeStringAndClear();
1767 void lcl_ScDocShell_WriteEmptyFixedWidthString( SvStream
& rStream
,
1768 const ScDocument
& rDoc
, SCTAB nTab
, SCCOL nCol
)
1771 lcl_ScDocShell_GetFixedWidthString( aString
, rDoc
, nTab
, nCol
, false,
1772 SVX_HOR_JUSTIFY_STANDARD
);
1773 rStream
.WriteUnicodeOrByteText( aString
);
1776 template<typename StrT
, typename SepCharT
>
1777 sal_Int32
getTextSepPos(
1778 const StrT
& rStr
, const ScImportOptions
& rAsciiOpt
, const SepCharT
& rTextSep
, const SepCharT
& rFieldSep
, bool& rNeedQuotes
)
1780 // #i116636# quotes are needed if text delimiter (quote), field delimiter,
1781 // or LF is in the cell text.
1782 sal_Int32 nPos
= rStr
.indexOf(rTextSep
);
1783 rNeedQuotes
= rAsciiOpt
.bQuoteAllText
|| (nPos
>= 0) ||
1784 (rStr
.indexOf(rFieldSep
) >= 0) ||
1785 (rStr
.indexOf('\n') >= 0);
1789 template<typename StrT
, typename StrBufT
>
1790 void escapeTextSep(sal_Int32 nPos
, const StrT
& rStrDelim
, StrT
& rStr
)
1795 aBuf
.insert(nPos
, rStrDelim
);
1796 rStr
= aBuf
.makeStringAndClear();
1797 nPos
= rStr
.indexOf(rStrDelim
, nPos
+1+rStrDelim
.getLength());
1803 void ScDocShell::AsciiSave( SvStream
& rStream
, const ScImportOptions
& rAsciiOpt
)
1805 sal_Unicode cDelim
= rAsciiOpt
.nFieldSepCode
;
1806 sal_Unicode cStrDelim
= rAsciiOpt
.nTextSepCode
;
1807 rtl_TextEncoding eCharSet
= rAsciiOpt
.eCharSet
;
1808 bool bFixedWidth
= rAsciiOpt
.bFixedWidth
;
1809 bool bSaveAsShown
= rAsciiOpt
.bSaveAsShown
;
1810 bool bShowFormulas
= rAsciiOpt
.bSaveFormulas
;
1812 rtl_TextEncoding eOldCharSet
= rStream
.GetStreamCharSet();
1813 rStream
.SetStreamCharSet( eCharSet
);
1814 SvStreamEndian nOldNumberFormatInt
= rStream
.GetEndian();
1815 OString aStrDelimEncoded
; // only used if not Unicode
1816 OUString aStrDelimDecoded
; // only used if context encoding
1817 OString aDelimEncoded
;
1818 OUString aDelimDecoded
;
1819 bool bContextOrNotAsciiEncoding
;
1820 if ( eCharSet
== RTL_TEXTENCODING_UNICODE
)
1822 rStream
.StartWritingUnicodeText();
1823 bContextOrNotAsciiEncoding
= false;
1827 aStrDelimEncoded
= OString(&cStrDelim
, 1, eCharSet
);
1828 aDelimEncoded
= OString(&cDelim
, 1, eCharSet
);
1829 rtl_TextEncodingInfo aInfo
;
1830 aInfo
.StructSize
= sizeof(aInfo
);
1831 if ( rtl_getTextEncodingInfo( eCharSet
, &aInfo
) )
1833 bContextOrNotAsciiEncoding
=
1834 (((aInfo
.Flags
& RTL_TEXTENCODING_INFO_CONTEXT
) != 0) ||
1835 ((aInfo
.Flags
& RTL_TEXTENCODING_INFO_ASCII
) == 0));
1836 if ( bContextOrNotAsciiEncoding
)
1838 aStrDelimDecoded
= OStringToOUString(aStrDelimEncoded
, eCharSet
);
1839 aDelimDecoded
= OStringToOUString(aDelimEncoded
, eCharSet
);
1843 bContextOrNotAsciiEncoding
= false;
1846 SCCOL nStartCol
= 0;
1847 SCROW nStartRow
= 0;
1848 SCTAB nTab
= GetSaveTab();
1851 aDocument
.GetCellArea( nTab
, nEndCol
, nEndRow
);
1853 ScProgress
aProgress( this, ScGlobal::GetRscString( STR_SAVE_DOC
), nEndRow
);
1857 bool bTabProtect
= aDocument
.IsTabProtected( nTab
);
1861 SCCOL nNextCol
= nStartCol
;
1862 SCROW nNextRow
= nStartRow
;
1865 SvNumberFormatter
& rFormatter
= *aDocument
.GetFormatTable();
1867 ScHorizontalCellIterator
aIter( &aDocument
, nTab
, nStartCol
, nStartRow
,
1869 ScRefCellValue
* pCell
;
1870 while ( ( pCell
= aIter
.GetNext( nCol
, nRow
) ) != NULL
)
1872 bool bProgress
= false; // only upon line change
1873 if ( nNextRow
< nRow
)
1874 { // empty rows or/and empty columns up to end of row
1876 for ( nEmptyCol
= nNextCol
; nEmptyCol
< nEndCol
; nEmptyCol
++ )
1877 { // remaining columns of last row
1879 lcl_ScDocShell_WriteEmptyFixedWidthString( rStream
,
1880 aDocument
, nTab
, nEmptyCol
);
1881 else if ( cDelim
!= 0 )
1882 rStream
.WriteUniOrByteChar( cDelim
);
1886 for ( nEmptyRow
= nNextRow
; nEmptyRow
< nRow
; nEmptyRow
++ )
1887 { // completely empty rows
1888 for ( nEmptyCol
= nStartCol
; nEmptyCol
< nEndCol
; nEmptyCol
++ )
1891 lcl_ScDocShell_WriteEmptyFixedWidthString( rStream
,
1892 aDocument
, nTab
, nEmptyCol
);
1893 else if ( cDelim
!= 0 )
1894 rStream
.WriteUniOrByteChar( cDelim
);
1898 for ( nEmptyCol
= nStartCol
; nEmptyCol
< nCol
; nEmptyCol
++ )
1899 { // empty columns at beginning of row
1901 lcl_ScDocShell_WriteEmptyFixedWidthString( rStream
,
1902 aDocument
, nTab
, nEmptyCol
);
1903 else if ( cDelim
!= 0 )
1904 rStream
.WriteUniOrByteChar( cDelim
);
1908 else if ( nNextCol
< nCol
)
1909 { // empty columns in same row
1910 for ( nEmptyCol
= nNextCol
; nEmptyCol
< nCol
; nEmptyCol
++ )
1911 { // columns in between
1913 lcl_ScDocShell_WriteEmptyFixedWidthString( rStream
,
1914 aDocument
, nTab
, nEmptyCol
);
1915 else if ( cDelim
!= 0 )
1916 rStream
.WriteUniOrByteChar( cDelim
);
1919 if ( nCol
== nEndCol
)
1922 nNextCol
= nStartCol
;
1923 nNextRow
= nRow
+ 1;
1926 nNextCol
= nCol
+ 1;
1928 CellType eType
= pCell
->meType
;
1929 ScAddress
aPos(nCol
, nRow
, nTab
);
1932 const ScProtectionAttr
* pProtAttr
=
1933 static_cast<const ScProtectionAttr
*>( aDocument
.GetAttr(
1934 nCol
, nRow
, nTab
, ATTR_PROTECTION
));
1935 if ( pProtAttr
->GetHideCell() ||
1936 ( eType
== CELLTYPE_FORMULA
&& bShowFormulas
&&
1937 pProtAttr
->GetHideFormula() ) )
1938 eType
= CELLTYPE_NONE
; // hide
1947 case CELLTYPE_FORMULA
:
1949 sal_uInt16 nErrCode
;
1950 if ( bShowFormulas
)
1952 pCell
->mpFormula
->GetFormula(aString
);
1955 else if ((nErrCode
= pCell
->mpFormula
->GetErrCode()) != 0)
1957 aString
= ScGlobal::GetErrorString( nErrCode
);
1960 else if (pCell
->mpFormula
->IsValue())
1962 sal_uInt32 nFormat
= aDocument
.GetNumberFormat(aPos
);
1963 if ( bFixedWidth
|| bSaveAsShown
)
1966 aString
= ScCellFormat::GetString(aDocument
, aPos
, nFormat
, &pDummy
, rFormatter
);
1967 bString
= bSaveAsShown
&& rFormatter
.IsTextFormat( nFormat
);
1971 ScCellFormat::GetInputString(*pCell
, nFormat
, aString
, rFormatter
, &aDocument
);
1979 sal_uInt32 nFormat
= aDocument
.GetNumberFormat(aPos
);
1981 aString
= ScCellFormat::GetString(aDocument
, aPos
, nFormat
, &pDummy
, rFormatter
);
1984 aString
= pCell
->mpFormula
->GetString().getString();
1989 case CELLTYPE_STRING
:
1992 sal_uInt32 nFormat
= aDocument
.GetNumberFormat(aPos
);
1994 aString
= ScCellFormat::GetString(aDocument
, aPos
, nFormat
, &pDummy
, rFormatter
);
1997 aString
= pCell
->mpString
->getString();
2000 case CELLTYPE_EDIT
:
2002 const EditTextObject
* pObj
= pCell
->mpEditText
;
2003 EditEngine
& rEngine
= aDocument
.GetEditEngine();
2004 rEngine
.SetText( *pObj
);
2005 aString
= rEngine
.GetText(); // including LF
2009 case CELLTYPE_VALUE
:
2012 aDocument
.GetNumberFormat( nCol
, nRow
, nTab
, nFormat
);
2013 if ( bFixedWidth
|| bSaveAsShown
)
2016 aString
= ScCellFormat::GetString(aDocument
, aPos
, nFormat
, &pDummy
, rFormatter
);
2017 bString
= bSaveAsShown
&& rFormatter
.IsTextFormat( nFormat
);
2021 ScCellFormat::GetInputString(*pCell
, nFormat
, aString
, rFormatter
, &aDocument
);
2027 OSL_FAIL( "ScDocShell::AsciiSave: unknown CellType" );
2034 SvxCellHorJustify eHorJust
= (SvxCellHorJustify
)
2035 static_cast<const SvxHorJustifyItem
*>( aDocument
.GetAttr( nCol
, nRow
,
2036 nTab
, ATTR_HOR_JUSTIFY
))->GetValue();
2037 lcl_ScDocShell_GetFixedWidthString( aString
, aDocument
, nTab
, nCol
,
2038 !bString
, eHorJust
);
2039 rStream
.WriteUnicodeOrByteText( aString
);
2043 OUString aUniString
= aString
;// TODO: remove that later
2044 if (!bString
&& cStrDelim
!= 0 && !aUniString
.isEmpty())
2046 sal_Unicode c
= aUniString
[0];
2047 bString
= (c
== cStrDelim
|| c
== ' ' ||
2048 aUniString
.endsWith(" ") ||
2049 aUniString
.indexOf(cStrDelim
) >= 0);
2050 if (!bString
&& cDelim
!= 0)
2051 bString
= (aUniString
.indexOf(cDelim
) >= 0);
2055 if ( cStrDelim
!= 0 ) //@ BugId 55355
2057 if ( eCharSet
== RTL_TEXTENCODING_UNICODE
)
2059 bool bNeedQuotes
= false;
2060 sal_Int32 nPos
= getTextSepPos(
2061 aUniString
, rAsciiOpt
, cStrDelim
, cDelim
, bNeedQuotes
);
2063 escapeTextSep
<OUString
, OUStringBuffer
>(
2064 nPos
, OUString(cStrDelim
), aUniString
);
2067 rStream
.WriteUniOrByteChar( cStrDelim
, eCharSet
);
2068 write_uInt16s_FromOUString(rStream
, aUniString
);
2070 rStream
.WriteUniOrByteChar( cStrDelim
, eCharSet
);
2074 // This is nasty. The Unicode to byte encoding
2075 // may convert typographical quotation marks to ASCII
2076 // quotation marks, which may interfer with the delimiter,
2077 // so we have to escape delimiters after the string has
2078 // been encoded. Since this may happen also with UTF-8
2079 // encoded typographical quotation marks if such was
2080 // specified as a delimiter we have to check for the full
2081 // encoded delimiter string, not just one character.
2082 // Now for RTL_TEXTENCODING_ISO_2022_... and similar brain
2083 // dead encodings where one code point (and especially a
2084 // low ASCII value) may represent different characters, we
2085 // have to convert forth and back and forth again. Same for
2086 // UTF-7 since it is a context sensitive encoding too.
2088 if ( bContextOrNotAsciiEncoding
)
2091 OString aStrEnc
= OUStringToOString(aUniString
, eCharSet
);
2093 OUString aStrDec
= OStringToOUString(aStrEnc
, eCharSet
);
2095 // search on re-decoded string
2096 bool bNeedQuotes
= false;
2097 sal_Int32 nPos
= getTextSepPos(
2098 aStrDec
, rAsciiOpt
, aStrDelimDecoded
, aDelimDecoded
, bNeedQuotes
);
2100 escapeTextSep
<OUString
, OUStringBuffer
>(
2101 nPos
, aStrDelimDecoded
, aStrDec
);
2103 // write byte re-encoded
2105 rStream
.WriteUniOrByteChar( cStrDelim
, eCharSet
);
2106 rStream
.WriteUnicodeOrByteText( aStrDec
, eCharSet
);
2108 rStream
.WriteUniOrByteChar( cStrDelim
, eCharSet
);
2112 OString aStrEnc
= OUStringToOString(aUniString
, eCharSet
);
2114 // search on encoded string
2115 bool bNeedQuotes
= false;
2116 sal_Int32 nPos
= getTextSepPos(
2117 aStrEnc
, rAsciiOpt
, aStrDelimEncoded
, aDelimEncoded
, bNeedQuotes
);
2119 escapeTextSep
<OString
, OStringBuffer
>(
2120 nPos
, aStrDelimEncoded
, aStrEnc
);
2122 // write byte encoded
2125 aStrDelimEncoded
.getStr(), aStrDelimEncoded
.getLength());
2126 rStream
.Write(aStrEnc
.getStr(), aStrEnc
.getLength());
2129 aStrDelimEncoded
.getStr(), aStrDelimEncoded
.getLength());
2134 rStream
.WriteUnicodeOrByteText( aUniString
);
2137 rStream
.WriteUnicodeOrByteText( aUniString
);
2140 if( nCol
< nEndCol
)
2142 if(cDelim
!=0) //@ BugId 55355
2143 rStream
.WriteUniOrByteChar( cDelim
);
2149 aProgress
.SetStateOnPercent( nRow
);
2152 // write out empty if requested
2153 if ( nNextRow
<= nEndRow
)
2155 for ( nEmptyCol
= nNextCol
; nEmptyCol
< nEndCol
; nEmptyCol
++ )
2156 { // remaining empty columns of last row
2158 lcl_ScDocShell_WriteEmptyFixedWidthString( rStream
,
2159 aDocument
, nTab
, nEmptyCol
);
2160 else if ( cDelim
!= 0 )
2161 rStream
.WriteUniOrByteChar( cDelim
);
2166 for ( nEmptyRow
= nNextRow
; nEmptyRow
<= nEndRow
; nEmptyRow
++ )
2167 { // entire empty rows
2168 for ( nEmptyCol
= nStartCol
; nEmptyCol
< nEndCol
; nEmptyCol
++ )
2171 lcl_ScDocShell_WriteEmptyFixedWidthString( rStream
,
2172 aDocument
, nTab
, nEmptyCol
);
2173 else if ( cDelim
!= 0 )
2174 rStream
.WriteUniOrByteChar( cDelim
);
2179 rStream
.SetStreamCharSet( eOldCharSet
);
2180 rStream
.SetEndian( nOldNumberFormatInt
);
2183 bool ScDocShell::ConvertTo( SfxMedium
&rMed
)
2185 ScRefreshTimerProtector
aProt( aDocument
.GetRefreshTimerControlAddress() );
2187 // #i6500# don't call DoEnterHandler here (doesn't work with AutoSave),
2188 // it's already in ExecuteSave (as for Save and SaveAs)
2191 pAutoStyleList
->ExecuteAllNow(); // Execute template timeouts now
2192 if (GetCreateMode()== SfxObjectCreateMode::STANDARD
)
2193 SfxObjectShell::SetVisArea( Rectangle() ); // Edited normally -> no VisArea
2195 OSL_ENSURE( rMed
.GetFilter(), "Filter == 0" );
2198 OUString aFltName
= rMed
.GetFilter()->GetFilterName();
2200 if (aFltName
== pFilterXML
)
2202 //TODO/LATER: this shouldn't happen!
2203 OSL_FAIL("XML filter in ConvertFrom?!");
2204 bRet
= SaveXML( &rMed
, NULL
);
2206 else if (aFltName
== pFilterExcel5
|| aFltName
== pFilterExcel95
||
2207 aFltName
== pFilterExcel97
|| aFltName
== pFilterEx5Temp
||
2208 aFltName
== pFilterEx95Temp
|| aFltName
== pFilterEx97Temp
)
2210 WaitObject
aWait( GetActiveDialogParent() );
2212 bool bDoSave
= true;
2213 if( ScTabViewShell
* pViewShell
= GetBestViewShell() )
2215 ScExtDocOptions
* pExtDocOpt
= aDocument
.GetExtDocOptions();
2217 aDocument
.SetExtDocOptions( pExtDocOpt
= new ScExtDocOptions
);
2218 pViewShell
->GetViewData().WriteExtOptions( *pExtDocOpt
);
2220 /* #i104990# If the imported document contains a medium
2221 password, determine if we can save it, otherwise ask the users
2222 whether they want to save without it. */
2223 if( (rMed
.GetFilter()->GetFilterFlags() & SfxFilterFlags::ENCRYPTION
) == SfxFilterFlags::NONE
)
2225 SfxItemSet
* pItemSet
= rMed
.GetItemSet();
2226 const SfxPoolItem
* pItem
= 0;
2227 if( pItemSet
&& pItemSet
->GetItemState( SID_PASSWORD
, true, &pItem
) == SfxItemState::SET
)
2229 bDoSave
= ScWarnPassword::WarningOnPassword( rMed
);
2230 // #i42858# remove password from medium (warn only one time)
2232 pItemSet
->ClearItem( SID_PASSWORD
);
2238 bool bNeedRetypePassDlg
= ScPassHashHelper::needsPassHashRegen( aDocument
, PASSHASH_XL
);
2239 bDoSave
= !bNeedRetypePassDlg
|| pViewShell
->ExecuteRetypePassDlg( PASSHASH_XL
);
2245 ExportFormatExcel eFormat
= ExpBiff5
;
2246 if( aFltName
== pFilterExcel97
|| aFltName
== pFilterEx97Temp
)
2248 FltError eError
= ScFormatFilter::Get().ScExportExcel5( rMed
, &aDocument
, eFormat
, RTL_TEXTENCODING_MS_1252
);
2250 if( eError
&& !GetError() )
2251 SetError( eError
, OUString( OSL_LOG_PREFIX
) );
2253 // don't return false for warnings
2254 bRet
= ((eError
& ERRCODE_WARNING_MASK
) == ERRCODE_WARNING_MASK
) || (eError
== eERR_OK
);
2258 // export aborted, i.e. "Save without password" warning
2259 SetError( ERRCODE_ABORT
, OUString( OSL_LOG_PREFIX
) );
2262 else if (aFltName
== pFilterAscii
)
2264 SvStream
* pStream
= rMed
.GetOutStream();
2268 SfxItemSet
* pSet
= rMed
.GetItemSet();
2269 const SfxPoolItem
* pItem
;
2270 if ( pSet
&& SfxItemState::SET
==
2271 pSet
->GetItemState( SID_FILE_FILTEROPTIONS
, true, &pItem
) )
2273 sItStr
= static_cast<const SfxStringItem
*>(pItem
)->GetValue();
2276 if ( sItStr
.isEmpty() )
2278 // default for ascii export (from API without options):
2279 // ISO8859-1/MS_1252 encoding, comma, double quotes
2281 ScImportOptions
aDefOptions( ',', '"', RTL_TEXTENCODING_MS_1252
);
2282 sItStr
= aDefOptions
.BuildString();
2285 WaitObject
aWait( GetActiveDialogParent() );
2286 ScImportOptions
aOptions( sItStr
);
2287 AsciiSave( *pStream
, aOptions
);
2290 if (aDocument
.GetTableCount() > 1)
2291 if (!rMed
.GetError())
2292 rMed
.SetError(SCWARN_EXPORT_ASCII
, OUString( OSL_LOG_PREFIX
));
2295 else if (aFltName
== pFilterDBase
)
2298 SfxItemSet
* pSet
= rMed
.GetItemSet();
2299 const SfxPoolItem
* pItem
;
2300 if ( pSet
&& SfxItemState::SET
==
2301 pSet
->GetItemState( SID_FILE_FILTEROPTIONS
, true, &pItem
) )
2303 sCharSet
= static_cast<const SfxStringItem
*>(pItem
)->GetValue();
2306 if (sCharSet
.isEmpty())
2308 // default for dBase export (from API without options):
2311 sCharSet
= ScGlobal::GetCharsetString( RTL_TEXTENCODING_IBM_850
);
2314 WaitObject
aWait( GetActiveDialogParent() );
2315 // FIXME: Hack so that the Sba opened TempFile can be overwritten
2316 rMed
.CloseOutStream();
2317 bool bHasMemo
= false;
2319 sal_uLong eError
= DBaseExport(
2320 rMed
.GetPhysicalName(), ScGlobal::GetCharsetValue(sCharSet
), bHasMemo
);
2322 if ( eError
!= eERR_OK
&& (eError
& ERRCODE_WARNING_MASK
) )
2327 INetURLObject
aTmpFile( rMed
.GetPhysicalName(), INetProtocol::File
);
2329 aTmpFile
.setExtension(OUString("dbt"));
2330 if ( eError
!= eERR_OK
)
2333 SetError(eError
, OUString( OSL_LOG_PREFIX
));
2334 if ( bHasMemo
&& IsDocument( aTmpFile
) )
2335 KillFile( aTmpFile
);
2342 const SfxStringItem
* pNameItem
=
2343 static_cast<const SfxStringItem
*>( rMed
.GetItemSet()->GetItem( SID_FILE_NAME
) );
2344 INetURLObject
aDbtFile( pNameItem
->GetValue(), INetProtocol::File
);
2345 aDbtFile
.setExtension(OUString("dbt"));
2346 if ( IsDocument( aDbtFile
) && !KillFile( aDbtFile
) )
2348 if ( bRet
&& !MoveFile( aTmpFile
, aDbtFile
) )
2352 KillFile( aTmpFile
);
2354 SetError( SCERR_EXPORT_DATA
, OUString( OSL_LOG_PREFIX
) );
2359 else if (aFltName
== pFilterDif
)
2361 SvStream
* pStream
= rMed
.GetOutStream();
2365 SfxItemSet
* pSet
= rMed
.GetItemSet();
2366 const SfxPoolItem
* pItem
;
2367 if ( pSet
&& SfxItemState::SET
==
2368 pSet
->GetItemState( SID_FILE_FILTEROPTIONS
, true, &pItem
) )
2370 sItStr
= static_cast<const SfxStringItem
*>(pItem
)->GetValue();
2373 if (sItStr
.isEmpty())
2375 // default for DIF export (from API without options):
2376 // ISO8859-1/MS_1252 encoding
2378 sItStr
= ScGlobal::GetCharsetString( RTL_TEXTENCODING_MS_1252
);
2381 WaitObject
aWait( GetActiveDialogParent() );
2382 ScFormatFilter::Get().ScExportDif( *pStream
, &aDocument
, ScAddress(0,0,0),
2383 ScGlobal::GetCharsetValue(sItStr
) );
2386 if (aDocument
.GetTableCount() > 1)
2387 if (!rMed
.GetError())
2388 rMed
.SetError(SCWARN_EXPORT_ASCII
, OUString( OSL_LOG_PREFIX
));
2391 else if (aFltName
== pFilterSylk
)
2393 SvStream
* pStream
= rMed
.GetOutStream();
2396 WaitObject
aWait( GetActiveDialogParent() );
2400 aDocument
.GetCellArea( 0, nEndCol
, nEndRow
);
2401 ScRange
aRange( 0,0,0, nEndCol
,nEndRow
,0 );
2403 ScImportExport
aImExport( &aDocument
, aRange
);
2404 aImExport
.SetFormulas( true );
2405 bRet
= aImExport
.ExportStream( *pStream
, rMed
.GetBaseURL( true ), SotClipboardFormatId::SYLK
);
2408 else if (aFltName
== pFilterHtml
)
2410 SvStream
* pStream
= rMed
.GetOutStream();
2413 SfxItemSet
* pSet
= rMed
.GetItemSet();
2414 const SfxPoolItem
* pItem
;
2415 OUString sFilterOptions
;
2417 if (pSet
->GetItemState(SID_FILE_FILTEROPTIONS
, true, &pItem
) == SfxItemState::SET
)
2418 sFilterOptions
= static_cast<const SfxStringItem
*>(pItem
)->GetValue();
2420 WaitObject
aWait(GetActiveDialogParent());
2421 ScImportExport
aImExport(&aDocument
);
2422 aImExport
.SetStreamPath(rMed
.GetName());
2423 aImExport
.SetFilterOptions(sFilterOptions
);
2424 bRet
= aImExport
.ExportStream(*pStream
, rMed
.GetBaseURL(true), SotClipboardFormatId::HTML
);
2425 if (bRet
&& !aImExport
.GetNonConvertibleChars().isEmpty())
2427 SetError(*new StringErrorInfo(
2428 SCWARN_EXPORT_NONCONVERTIBLE_CHARS
,
2429 aImExport
.GetNonConvertibleChars(),
2430 ERRCODE_BUTTON_OK
| ERRCODE_MSG_INFO
), OUString(OSL_LOG_PREFIX
));
2437 SetError(SCERR_IMPORT_NI
, OUString(OSL_LOG_PREFIX
));
2442 bool ScDocShell::SaveCompleted( const uno::Reference
< embed::XStorage
>& xStor
)
2444 return SfxObjectShell::SaveCompleted( xStor
);
2447 bool ScDocShell::DoSaveCompleted( SfxMedium
* pNewStor
)
2449 bool bRet
= SfxObjectShell::DoSaveCompleted( pNewStor
);
2451 // SC_HINT_DOC_SAVED for change ReadOnly -> Read/Write
2452 Broadcast( SfxSimpleHint( SC_HINT_DOC_SAVED
) );
2456 bool ScDocShell::QuerySlotExecutable( sal_uInt16 nSlotId
)
2458 // #i112634# ask VBA event handlers whether to save or print the document
2460 using namespace ::com::sun::star::script::vba
;
2462 sal_Int32 nVbaEventId
= VBAEventId::NO_EVENT
;
2463 uno::Sequence
< uno::Any
> aArgs
;
2468 nVbaEventId
= VBAEventId::WORKBOOK_BEFORESAVE
;
2470 aArgs
[ 0 ] <<= (nSlotId
== SID_SAVEASDOC
);
2473 case SID_PRINTDOCDIRECT
:
2474 nVbaEventId
= VBAEventId::WORKBOOK_BEFOREPRINT
;
2478 bool bSlotExecutable
= true;
2479 if( nVbaEventId
!= VBAEventId::NO_EVENT
) try
2481 uno::Reference
< XVBAEventProcessor
> xEventProcessor( aDocument
.GetVbaEventProcessor(), uno::UNO_QUERY_THROW
);
2482 xEventProcessor
->processVbaEvent( nVbaEventId
, aArgs
);
2484 catch( util::VetoException
& )
2486 bSlotExecutable
= false;
2488 catch( uno::Exception
& )
2491 return bSlotExecutable
;
2494 bool ScDocShell::PrepareClose( bool bUI
)
2496 if(SC_MOD()->GetCurRefDlgId()>0)
2498 SfxViewFrame
* pFrame
= SfxViewFrame::GetFirst( this );
2501 SfxViewShell
* p
= pFrame
->GetViewShell();
2502 ScTabViewShell
* pViewSh
= PTR_CAST(ScTabViewShell
,p
);
2505 vcl::Window
*pWin
=pViewSh
->GetWindow();
2506 if(pWin
!=NULL
) pWin
->GrabFocus();
2512 if ( aDocument
.IsInLinkUpdate() || aDocument
.IsInInterpreter() )
2514 ErrorMessage(STR_CLOSE_ERROR_LINK
);
2520 // start 'Workbook_BeforeClose' VBA event handler for possible veto
2521 if( !IsInPrepareClose() )
2525 uno::Reference
< script::vba::XVBAEventProcessor
> xVbaEvents( aDocument
.GetVbaEventProcessor(), uno::UNO_SET_THROW
);
2526 uno::Sequence
< uno::Any
> aArgs
;
2527 xVbaEvents
->processVbaEvent( script::vba::VBAEventId::WORKBOOK_BEFORECLOSE
, aArgs
);
2529 catch( util::VetoException
& )
2531 // if event processor throws VetoException, macro has vetoed close
2534 catch( uno::Exception
& )
2540 bool nRet
= SfxObjectShell::PrepareClose( bUI
);
2541 if (nRet
) // true == close
2542 aDocument
.EnableIdle(false); // Do not mess around with it anymore!
2547 void ScDocShell::PrepareReload()
2549 SfxObjectShell::PrepareReload(); // FIXME: Doesn't do a thing?
2551 // The Disconnect of DDE Links can trigger a Reschedule.
2552 // If the DDE Links are not deleted before the Document dtor,
2553 // the DDE Link Update for this Document can be triggered ofrom this Reschedule on Reload.
2554 // This causes a hang.
2556 // Thus: Disconnect the DDE Links of the old Document before Reload
2557 aDocument
.GetDocLinkManager().disconnectDdeLinks();
2560 OUString
ScDocShell::GetOwnFilterName()
2562 return OUString(pFilterSc50
);
2565 OUString
ScDocShell::GetHtmlFilterName()
2567 return OUString(pFilterHtml
);
2570 OUString
ScDocShell::GetWebQueryFilterName()
2572 return OUString(pFilterHtmlWebQ
);
2575 OUString
ScDocShell::GetAsciiFilterName()
2577 return OUString(pFilterAscii
);
2580 OUString
ScDocShell::GetLotusFilterName()
2582 return OUString(pFilterLotus
);
2585 OUString
ScDocShell::GetDBaseFilterName()
2587 return OUString(pFilterDBase
);
2590 OUString
ScDocShell::GetDifFilterName()
2592 return OUString(pFilterDif
);
2595 bool ScDocShell::HasAutomaticTableName( const OUString
& rFilter
)
2597 // sal_True for those filters that keep the default table name
2598 // (which is language specific)
2600 return rFilter
== pFilterAscii
2601 || rFilter
== pFilterLotus
2602 || rFilter
== pFilterExcel4
2603 || rFilter
== pFilterEx4Temp
2604 || rFilter
== pFilterDBase
2605 || rFilter
== pFilterDif
2606 || rFilter
== pFilterSylk
2607 || rFilter
== pFilterHtml
2608 || rFilter
== pFilterRtf
;
2611 #if ! ENABLE_TELEPATHY
2612 ScDocFunc
*ScDocShell::CreateDocFunc()
2614 return new ScDocFuncDirect( *this );
2617 ScCollaboration
* ScDocShell::GetCollaboration()
2619 return mpCollaboration
;
2623 ScDocShell::ScDocShell( const ScDocShell
& rShell
) :
2626 SfxObjectShell( rShell
.GetCreateMode() ),
2628 aDocument ( SCDOCMODE_DOCUMENT
, this ),
2629 aDdeTextFmt(OUString("TEXT")),
2630 nPrtToScreenFactor( 1.0 ),
2631 pImpl ( new DocShell_Impl
),
2635 bIsInUndo ( false ),
2636 bDocumentModifiedPending( false ),
2637 bUpdateEnabled ( true ),
2638 nDocumentLock ( 0 ),
2639 nCanUpdate (com::sun::star::document::UpdateDocMode::ACCORDING_TO_CONFIG
),
2640 pOldAutoDBRange ( NULL
),
2641 pDocHelper ( NULL
),
2642 pAutoStyleList ( NULL
),
2643 pPaintLockData ( NULL
),
2644 pSolverSaveData ( NULL
),
2645 pSheetSaveData ( NULL
),
2646 pModificator ( NULL
)
2647 #if ENABLE_TELEPATHY
2648 , mpCollaboration( new ScCollaboration( this ) )
2651 SetPool( &SC_MOD()->GetPool() );
2653 bIsInplace
= rShell
.bIsInplace
;
2655 pDocFunc
= CreateDocFunc();
2657 // SetBaseModel needs exception handling
2658 ScModelObj::CreateAndSet( this );
2660 StartListening(*this);
2661 SfxStyleSheetPool
* pStlPool
= aDocument
.GetStyleSheetPool();
2663 StartListening(*pStlPool
);
2665 GetPageOnFromPageStyleSet( NULL
, 0, bHeaderOn
, bFooterOn
);
2666 SetHelpId( HID_SCSHELL_DOCSH
);
2668 // InitItems and CalcOutputFactor are called now in Load/ConvertFrom/InitNew
2671 ScDocShell::ScDocShell( const SfxModelFlags i_nSfxCreationFlags
) :
2672 SfxObjectShell( i_nSfxCreationFlags
),
2673 aDocument ( SCDOCMODE_DOCUMENT
, this ),
2674 aDdeTextFmt(OUString("TEXT")),
2675 nPrtToScreenFactor( 1.0 ),
2676 pImpl ( new DocShell_Impl
),
2680 bIsInUndo ( false ),
2681 bDocumentModifiedPending( false ),
2682 bUpdateEnabled ( true ),
2683 nDocumentLock ( 0 ),
2684 nCanUpdate (com::sun::star::document::UpdateDocMode::ACCORDING_TO_CONFIG
),
2685 pOldAutoDBRange ( NULL
),
2686 pDocHelper ( NULL
),
2687 pAutoStyleList ( NULL
),
2688 pPaintLockData ( NULL
),
2689 pSolverSaveData ( NULL
),
2690 pSheetSaveData ( NULL
),
2691 pModificator ( NULL
)
2692 #if ENABLE_TELEPATHY
2693 , mpCollaboration( new ScCollaboration( this ) )
2696 SetPool( &SC_MOD()->GetPool() );
2698 bIsInplace
= (GetCreateMode() == SfxObjectCreateMode::EMBEDDED
);
2699 // Will be reset if not in place
2701 pDocFunc
= CreateDocFunc();
2703 // SetBaseModel needs exception handling
2704 ScModelObj::CreateAndSet( this );
2706 StartListening(*this);
2707 SfxStyleSheetPool
* pStlPool
= aDocument
.GetStyleSheetPool();
2709 StartListening(*pStlPool
);
2710 SetHelpId( HID_SCSHELL_DOCSH
);
2712 aDocument
.GetDBCollection()->SetRefreshHandler(
2713 LINK( this, ScDocShell
, RefreshDBDataHdl
) );
2715 // InitItems and CalcOutputFactor are called now in Load/ConvertFrom/InitNew
2718 ScDocShell::~ScDocShell()
2720 ResetDrawObjectShell(); // If the Drawing Layer still tries to access it, access it
2722 SfxStyleSheetPool
* pStlPool
= aDocument
.GetStyleSheetPool();
2724 EndListening(*pStlPool
);
2725 EndListening(*this);
2727 delete pAutoStyleList
;
2729 SfxApplication
*pSfxApp
= SfxGetpApp();
2730 if ( pSfxApp
->GetDdeService() ) // Delete DDE for Document
2731 pSfxApp
->RemoveDdeTopic( this );
2734 delete aDocument
.mpUndoManager
;
2735 aDocument
.mpUndoManager
= 0;
2738 delete pPaintLockData
;
2740 delete pSolverSaveData
;
2741 delete pSheetSaveData
;
2742 delete pOldAutoDBRange
;
2746 OSL_FAIL("The Modificator should not exist");
2747 delete pModificator
;
2749 #if ENABLE_TELEPATHY
2750 delete mpCollaboration
;
2754 ::svl::IUndoManager
* ScDocShell::GetUndoManager()
2756 return aDocument
.GetUndoManager();
2759 void ScDocShell::SetModified( bool bModified
)
2761 if ( SfxObjectShell::IsEnableSetModified() )
2763 SfxObjectShell::SetModified( bModified
);
2764 Broadcast( SfxSimpleHint( SFX_HINT_DOCCHANGED
) );
2768 void ScDocShell::SetDocumentModified( bool bIsModified
/* = true */ )
2770 // BroadcastUno must also happen right away with pPaintLockData
2771 // FIXME: Also for SetDrawModified, if Drawing is connected
2772 // FIXME: Then own Hint?
2774 if ( pPaintLockData
&& bIsModified
)
2776 // #i115009# broadcast BCA_BRDCST_ALWAYS, so a component can read recalculated results
2777 // of RecalcModeAlways formulas (like OFFSET) after modifying cells
2778 aDocument
.Broadcast(ScHint(SC_HINT_DATACHANGED
, BCA_BRDCST_ALWAYS
));
2779 aDocument
.InvalidateTableArea(); // #i105279# needed here
2780 aDocument
.BroadcastUno( SfxSimpleHint( SFX_HINT_DATACHANGED
) );
2782 pPaintLockData
->SetModified(); // Later on ...
2786 SetDrawModified( bIsModified
);
2790 if ( aDocument
.IsAutoCalcShellDisabled() )
2791 SetDocumentModifiedPending( true );
2794 SetDocumentModifiedPending( false );
2795 aDocument
.InvalidateStyleSheetUsage();
2796 aDocument
.InvalidateTableArea();
2797 aDocument
.InvalidateLastTableOpParams();
2798 aDocument
.Broadcast(ScHint(SC_HINT_DATACHANGED
, BCA_BRDCST_ALWAYS
));
2799 if ( aDocument
.IsForcedFormulaPending() && aDocument
.GetAutoCalc() )
2800 aDocument
.CalcFormulaTree( true );
2803 // Detective AutoUpdate:
2804 // Update if formulas were modified (DetectiveDirty) or the list contains
2805 // "Trace Error" entries (Trace Error can look completely different
2806 // after changes to non-formula cells).
2808 ScDetOpList
* pList
= aDocument
.GetDetOpList();
2809 if ( pList
&& ( aDocument
.IsDetectiveDirty() || pList
->HasAddError() ) &&
2810 pList
->Count() && !IsInUndo() && SC_MOD()->GetAppOptions().GetDetectiveAuto() )
2812 GetDocFunc().DetectiveRefresh(true); // sal_True = caused by automatic update
2814 aDocument
.SetDetectiveDirty(false); // always reset, also if not refreshed
2817 // notify UNO objects after BCA_BRDCST_ALWAYS etc.
2818 aDocument
.BroadcastUno( SfxSimpleHint( SFX_HINT_DATACHANGED
) );
2823 * SetDrawModified - without Formula update
2825 * Drawing also needs to be updated for the normal SetDocumentModified
2826 * e.g.: when deleting tables etc.
2828 void ScDocShell::SetDrawModified( bool bIsModified
/* = true */ )
2830 bool bUpdate
= bIsModified
!= IsModified();
2832 SetModified( bIsModified
);
2834 SfxBindings
* pBindings
= GetViewBindings();
2839 pBindings
->Invalidate( SID_SAVEDOC
);
2840 pBindings
->Invalidate( SID_DOC_MODIFIED
);
2848 // #i105960# Undo etc used to be volatile.
2849 // They always have to be invalidated, including drawing layer or row height changes
2850 // (but not while pPaintLockData is set).
2851 pBindings
->Invalidate( SID_UNDO
);
2852 pBindings
->Invalidate( SID_REDO
);
2853 pBindings
->Invalidate( SID_REPEAT
);
2856 if ( aDocument
.IsChartListenerCollectionNeedsUpdate() )
2858 aDocument
.UpdateChartListenerCollection();
2859 SfxGetpApp()->Broadcast(SfxSimpleHint( SC_HINT_DRAW_CHANGED
)); // Navigator
2861 SC_MOD()->AnythingChanged();
2865 void ScDocShell::SetInUndo(bool bSet
)
2870 void ScDocShell::GetDocStat( ScDocStat
& rDocStat
)
2872 SfxPrinter
* pPrinter
= GetPrinter();
2874 aDocument
.GetDocStat( rDocStat
);
2875 rDocStat
.nPageCount
= 0;
2878 for ( SCTAB i
=0; i
<rDocStat
.nTableCount
; i
++ )
2879 rDocStat
.nPageCount
= sal::static_int_cast
<sal_uInt16
>( rDocStat
.nPageCount
+
2880 (sal_uInt16
) ScPrintFunc( this, pPrinter
, i
).GetTotalPages() );
2883 VclPtr
<SfxDocumentInfoDialog
> ScDocShell::CreateDocumentInfoDialog(
2884 vcl::Window
*pParent
, const SfxItemSet
&rSet
)
2886 VclPtr
<SfxDocumentInfoDialog
> pDlg
= VclPtr
<SfxDocumentInfoDialog
>::Create( pParent
, rSet
);
2887 ScDocShell
* pDocSh
= PTR_CAST(ScDocShell
,SfxObjectShell::Current());
2889 // Only for statistics, if this Doc is shown; not from the Doc Manager
2890 if( pDocSh
== this )
2892 ScAbstractDialogFactory
* pFact
= ScAbstractDialogFactory::Create();
2893 OSL_ENSURE(pFact
, "ScAbstractFactory create fail!");
2894 ::CreateTabPage ScDocStatPageCreate
= pFact
->GetTabPageCreatorFunc( RID_SCPAGE_STAT
);
2895 OSL_ENSURE(ScDocStatPageCreate
, "Tabpage create fail!");
2896 pDlg
->AddFontTabPage();
2897 pDlg
->AddTabPage( 42,
2898 ScGlobal::GetRscString( STR_DOC_STAT
),
2899 ScDocStatPageCreate
,
2905 vcl::Window
* ScDocShell::GetActiveDialogParent()
2907 ScTabViewShell
* pViewSh
= ScTabViewShell::GetActiveViewShell();
2909 return pViewSh
->GetDialogParent();
2911 return Application::GetDefDialogParent();
2914 void ScDocShell::SetSolverSaveData( const ScOptSolverSave
& rData
)
2916 delete pSolverSaveData
;
2917 pSolverSaveData
= new ScOptSolverSave( rData
);
2920 ScSheetSaveData
* ScDocShell::GetSheetSaveData()
2922 if (!pSheetSaveData
)
2923 pSheetSaveData
= new ScSheetSaveData
;
2925 return pSheetSaveData
;
2930 void removeKeysIfExists(Reference
<ui::XAcceleratorConfiguration
>& xScAccel
, const vector
<const awt::KeyEvent
*>& rKeys
)
2932 vector
<const awt::KeyEvent
*>::const_iterator itr
= rKeys
.begin(), itrEnd
= rKeys
.end();
2933 for (; itr
!= itrEnd
; ++itr
)
2935 const awt::KeyEvent
* p
= *itr
;
2941 xScAccel
->removeKeyEvent(*p
);
2943 catch (const container::NoSuchElementException
&) {}
2949 void ScDocShell::ResetKeyBindings( ScOptionsUtil::KeyBindingType eType
)
2951 using namespace ::com::sun::star::ui
;
2953 Reference
<uno::XComponentContext
> xContext
= ::comphelper::getProcessComponentContext();
2957 Reference
<XModuleUIConfigurationManagerSupplier
> xModuleCfgSupplier(
2958 theModuleUIConfigurationManagerSupplier::get(xContext
) );
2960 // Grab the Calc configuration.
2961 Reference
<XUIConfigurationManager
> xConfigMgr
=
2962 xModuleCfgSupplier
->getUIConfigurationManager(
2963 OUString("com.sun.star.sheet.SpreadsheetDocument"));
2965 if (!xConfigMgr
.is())
2969 Reference
<XAcceleratorConfiguration
> xScAccel
= xConfigMgr
->getShortCutManager();
2974 vector
<const awt::KeyEvent
*> aKeys
;
2978 awt::KeyEvent aBackspace
;
2979 aBackspace
.KeyCode
= awt::Key::BACKSPACE
;
2980 aBackspace
.Modifiers
= 0;
2981 aKeys
.push_back(&aBackspace
);
2984 awt::KeyEvent aDelete
;
2985 aDelete
.KeyCode
= awt::Key::DELETE
;
2986 aDelete
.Modifiers
= 0;
2987 aKeys
.push_back(&aDelete
);
2990 awt::KeyEvent aCtrlD
;
2991 aCtrlD
.KeyCode
= awt::Key::D
;
2992 aCtrlD
.Modifiers
= awt::KeyModifier::MOD1
;
2993 aKeys
.push_back(&aCtrlD
);
2996 awt::KeyEvent aAltDown
;
2997 aAltDown
.KeyCode
= awt::Key::DOWN
;
2998 aAltDown
.Modifiers
= awt::KeyModifier::MOD2
;
2999 aKeys
.push_back(&aAltDown
);
3001 // Remove all involved keys first, because swapping commands don't work
3002 // well without doing this.
3003 removeKeysIfExists(xScAccel
, aKeys
);
3008 case ScOptionsUtil::KEY_DEFAULT
:
3009 xScAccel
->setKeyEvent(aDelete
, OUString(".uno:ClearContents"));
3010 xScAccel
->setKeyEvent(aBackspace
, OUString(".uno:Delete"));
3011 xScAccel
->setKeyEvent(aCtrlD
, OUString(".uno:FillDown"));
3012 xScAccel
->setKeyEvent(aAltDown
, OUString(".uno:DataSelect"));
3014 case ScOptionsUtil::KEY_OOO_LEGACY
:
3015 xScAccel
->setKeyEvent(aDelete
, OUString(".uno:Delete"));
3016 xScAccel
->setKeyEvent(aBackspace
, OUString(".uno:ClearContents"));
3017 xScAccel
->setKeyEvent(aCtrlD
, OUString(".uno:DataSelect"));
3026 void ScDocShell::UseSheetSaveEntries()
3030 pSheetSaveData
->UseSaveEntries(); // use positions from saved file for next saving
3032 bool bHasEntries
= false;
3033 SCTAB nTabCount
= aDocument
.GetTableCount();
3035 for (nTab
= 0; nTab
< nTabCount
; ++nTab
)
3036 if (pSheetSaveData
->HasStreamPos(nTab
))
3041 // if no positions were set (for example, export to other format),
3042 // reset all "valid" flags
3044 for (nTab
= 0; nTab
< nTabCount
; ++nTab
)
3045 if (aDocument
.IsStreamValid(nTab
))
3046 aDocument
.SetStreamValid(nTab
, false);
3051 // --- ScDocShellModificator ------------------------------------------
3053 ScDocShellModificator::ScDocShellModificator( ScDocShell
& rDS
)
3056 mpProtector(new ScRefreshTimerProtector(rDS
.GetDocument().GetRefreshTimerControlAddress()))
3058 ScDocument
& rDoc
= rDocShell
.GetDocument();
3059 bAutoCalcShellDisabled
= rDoc
.IsAutoCalcShellDisabled();
3060 bIdleEnabled
= rDoc
.IsIdleEnabled();
3061 rDoc
.SetAutoCalcShellDisabled( true );
3062 rDoc
.EnableIdle(false);
3065 ScDocShellModificator::~ScDocShellModificator()
3067 ScDocument
& rDoc
= rDocShell
.GetDocument();
3068 rDoc
.SetAutoCalcShellDisabled( bAutoCalcShellDisabled
);
3069 if ( !bAutoCalcShellDisabled
&& rDocShell
.IsDocumentModifiedPending() )
3070 rDocShell
.SetDocumentModified(); // last one shuts off the lights
3071 rDoc
.EnableIdle(bIdleEnabled
);
3074 void ScDocShellModificator::SetDocumentModified()
3076 ScDocument
& rDoc
= rDocShell
.GetDocument();
3077 rDoc
.ClearFormulaContext();
3078 if ( !rDoc
.IsImportingXML() )
3080 // AutoCalcShellDisabled temporaer restaurieren
3081 bool bDisabled
= rDoc
.IsAutoCalcShellDisabled();
3082 rDoc
.SetAutoCalcShellDisabled( bAutoCalcShellDisabled
);
3083 rDocShell
.SetDocumentModified();
3084 rDoc
.SetAutoCalcShellDisabled( bDisabled
);
3088 // uno broadcast is necessary for api to work
3089 // -> must also be done during xml import
3090 rDoc
.BroadcastUno( SfxSimpleHint( SFX_HINT_DATACHANGED
) );
3094 bool ScDocShell::IsChangeRecording() const
3096 ScChangeTrack
* pChangeTrack
= aDocument
.GetChangeTrack();
3097 return pChangeTrack
!= NULL
;
3100 bool ScDocShell::HasChangeRecordProtection() const
3103 ScChangeTrack
* pChangeTrack
= aDocument
.GetChangeTrack();
3105 bRes
= pChangeTrack
->IsProtected();
3109 void ScDocShell::SetChangeRecording( bool bActivate
)
3111 bool bOldChangeRecording
= IsChangeRecording();
3115 aDocument
.StartChangeTracking();
3116 ScChangeViewSettings aChangeViewSet
;
3117 aChangeViewSet
.SetShowChanges(true);
3118 aDocument
.SetChangeViewSettings(aChangeViewSet
);
3122 aDocument
.EndChangeTracking();
3126 if (bOldChangeRecording
!= IsChangeRecording())
3128 UpdateAcceptChangesDialog();
3129 // Slots invalidieren
3130 SfxBindings
* pBindings
= GetViewBindings();
3132 pBindings
->InvalidateAll(false);
3136 bool ScDocShell::SetProtectionPassword( const OUString
&rNewPassword
)
3139 ScChangeTrack
* pChangeTrack
= aDocument
.GetChangeTrack();
3142 bool bProtected
= pChangeTrack
->IsProtected();
3144 if (!rNewPassword
.isEmpty())
3146 // when password protection is applied change tracking must always be active
3147 SetChangeRecording( true );
3149 ::com::sun::star::uno::Sequence
< sal_Int8
> aProtectionHash
;
3150 SvPasswordHelper::GetHashPassword( aProtectionHash
, rNewPassword
);
3151 pChangeTrack
->SetProtection( aProtectionHash
);
3155 pChangeTrack
->SetProtection( ::com::sun::star::uno::Sequence
< sal_Int8
>() );
3159 if ( bProtected
!= pChangeTrack
->IsProtected() )
3161 UpdateAcceptChangesDialog();
3162 SetDocumentModified();
3169 bool ScDocShell::GetProtectionHash( /*out*/ ::com::sun::star::uno::Sequence
< sal_Int8
> &rPasswordHash
)
3172 ScChangeTrack
* pChangeTrack
= aDocument
.GetChangeTrack();
3173 if (pChangeTrack
&& pChangeTrack
->IsProtected())
3175 rPasswordHash
= pChangeTrack
->GetProtection();
3181 void ScDocShell::libreOfficeKitCallback(int nType
, const char* pPayload
) const
3183 aDocument
.GetDrawLayer()->libreOfficeKitCallback(nType
, pPayload
);
3186 bool ScDocShell::isTiledRendering() const
3188 return aDocument
.GetDrawLayer() && aDocument
.GetDrawLayer()->isTiledRendering();
3191 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */