LibreOffice Module sc (master) 1
docsh.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <sal/config.h>
21
22#include <docsh.hxx>
23
24#include <config_features.h>
25#include <scitems.hxx>
26#include <sc.hrc>
27#include <vcl/errinf.hxx>
33#include <vcl/stdtext.hxx>
34#include <vcl/syswin.hxx>
35#include <vcl/svapp.hxx>
36#include <vcl/virdev.hxx>
37#include <vcl/weld.hxx>
38#include <rtl/bootstrap.hxx>
39#include <rtl/tencinfo.h>
40#include <sal/log.hxx>
42#include <sfx2/app.hxx>
43#include <sfx2/bindings.hxx>
44#include <sfx2/dinfdlg.hxx>
45#include <sfx2/docfile.hxx>
46#include <sfx2/event.hxx>
47#include <sfx2/docfilt.hxx>
48#include <sfx2/lokhelper.hxx>
49#include <sfx2/objface.hxx>
50#include <sfx2/viewfrm.hxx>
52#include <svl/fstathelper.hxx>
54#include <svl/urihelper.hxx>
55#include <osl/file.hxx>
56#include <chgtrack.hxx>
57#include <chgviset.hxx>
58#include <com/sun/star/awt/Key.hpp>
59#include <com/sun/star/awt/KeyModifier.hpp>
60#include <com/sun/star/container/XContentEnumerationAccess.hpp>
61#include <com/sun/star/document/UpdateDocMode.hpp>
62#include <com/sun/star/script/vba/VBAEventId.hpp>
63#include <com/sun/star/script/vba/VBAScriptEventId.hpp>
64#include <com/sun/star/script/vba/XVBAEventProcessor.hpp>
65#include <com/sun/star/script/vba/XVBAScriptListener.hpp>
66#include <com/sun/star/script/vba/XVBACompatibility.hpp>
67#include <com/sun/star/sheet/XSpreadsheetView.hpp>
68#include <com/sun/star/task/XJob.hpp>
69#include <com/sun/star/ui/theModuleUIConfigurationManagerSupplier.hpp>
70#include <com/sun/star/ui/XAcceleratorConfiguration.hpp>
71#include <com/sun/star/util/VetoException.hpp>
72#include <com/sun/star/lang/XSingleComponentFactory.hpp>
73#include <ooo/vba/excel/XWorkbook.hpp>
75
76#include <config_folders.h>
77
78#include <scabstdlg.hxx>
79#include <sot/formats.hxx>
80#include <svx/compatflags.hxx>
81#include <svx/dialogs.hrc>
82
83#include <formulacell.hxx>
84#include <global.hxx>
85#include <filter.hxx>
86#include <scmod.hxx>
87#include <tabvwsh.hxx>
88#include <docfunc.hxx>
89#include <imoptdlg.hxx>
90#include <impex.hxx>
91#include <scresid.hxx>
92#include <strings.hrc>
93#include <globstr.hrc>
94#include <scerrors.hxx>
95#include <brdcst.hxx>
96#include <stlpool.hxx>
97#include <autostyl.hxx>
98#include <attrib.hxx>
99#include <asciiopt.hxx>
100#include <progress.hxx>
101#include <pntlock.hxx>
102#include <docuno.hxx>
103#include <appoptio.hxx>
104#include <formulaopt.hxx>
105#include <scdll.hxx>
106#include <detdata.hxx>
107#include <printfun.hxx>
108#include <dociter.hxx>
109#include <cellform.hxx>
110#include <chartlis.hxx>
111#include <hints.hxx>
112#include <xmlwrap.hxx>
113#include <drwlayer.hxx>
114#include <dbdata.hxx>
115#include <scextopt.hxx>
116#include <compiler.hxx>
117#include <warnpassword.hxx>
118#include <optsolver.hxx>
119#include <sheetdata.hxx>
120#include <table.hxx>
121#include <tabprotection.hxx>
122#include <docparam.hxx>
123#include "docshimp.hxx"
124#include <sizedev.hxx>
125#include <undomanager.hxx>
127
128#include <officecfg/Office/Calc.hxx>
130#include <comphelper/string.hxx>
131#include <unotools/configmgr.hxx>
132#include <unotools/tempfile.hxx>
134#include <uiitems.hxx>
135#include <dpobject.hxx>
136#include <markdata.hxx>
137#include <docoptio.hxx>
139#include <datastream.hxx>
140#include <documentlinkmgr.hxx>
141#include <refupdatecontext.hxx>
142
143#include <memory>
144#include <vector>
145
146#include <comphelper/lok.hxx>
147#include <svtools/sfxecode.hxx>
149
150using namespace com::sun::star;
151using ::com::sun::star::uno::Reference;
152using ::com::sun::star::lang::XMultiServiceFactory;
153using std::shared_ptr;
154using ::std::vector;
155
156// Filter names (like in sclib.cxx)
157
158constexpr OUStringLiteral pFilterSc50 = u"StarCalc 5.0";
159const char pFilterXML[] = "StarOffice XML (Calc)";
160constexpr OUStringLiteral pFilterLotus = u"Lotus";
161const char pFilterQPro6[] = "Quattro Pro 6.0";
162const char16_t pFilterExcel4[] = u"MS Excel 4.0";
163const char16_t pFilterEx4Temp[] = u"MS Excel 4.0 Vorlage/Template";
164const char pFilterExcel5[] = "MS Excel 5.0/95";
165const char pFilterEx5Temp[] = "MS Excel 5.0/95 Vorlage/Template";
166const char pFilterExcel95[] = "MS Excel 95";
167const char pFilterEx95Temp[] = "MS Excel 95 Vorlage/Template";
168const char pFilterExcel97[] = "MS Excel 97";
169const char pFilterEx97Temp[] = "MS Excel 97 Vorlage/Template";
170constexpr OUStringLiteral pFilterDBase = u"dBase";
171constexpr OUStringLiteral pFilterDif = u"DIF";
172const char16_t pFilterSylk[] = u"SYLK";
173constexpr OUStringLiteral pFilterHtml = u"HTML (StarCalc)";
174constexpr OUStringLiteral pFilterHtmlWebQ = u"calc_HTML_WebQuery";
175const char16_t pFilterRtf[] = u"Rich Text Format (StarCalc)";
176
177#define ShellClass_ScDocShell
178#include <scslots.hxx>
179
181
182void ScDocShell::InitInterface_Impl()
183{
184}
185
186// GlobalName of the current version:
187SFX_IMPL_OBJECTFACTORY( ScDocShell, SvGlobalName(SO3_SC_CLASSID), "scalc" )
188
189
190void ScDocShell::FillClass( SvGlobalName* pClassName,
191 SotClipboardFormatId* pFormat,
192 OUString* pFullTypeName,
193 sal_Int32 nFileFormat,
194 bool bTemplate /* = false */) const
195{
196 if ( nFileFormat == SOFFICE_FILEFORMAT_60 )
197 {
198 *pClassName = SvGlobalName( SO3_SC_CLASSID_60 );
199 *pFormat = SotClipboardFormatId::STARCALC_60;
200 *pFullTypeName = ScResId( SCSTR_LONG_SCDOC_NAME_60 );
201 }
202 else if ( nFileFormat == SOFFICE_FILEFORMAT_8 )
203 {
204 *pClassName = SvGlobalName( SO3_SC_CLASSID_60 );
205 *pFormat = bTemplate ? SotClipboardFormatId::STARCALC_8_TEMPLATE : SotClipboardFormatId::STARCALC_8;
206 *pFullTypeName = ScResId( SCSTR_LONG_SCDOC_NAME_80 );
207 }
208 else
209 {
210 OSL_FAIL("Which version?");
211 }
212}
213
215{
216 return m_pDocument->GetDocColors();
217}
218
220{
222 if (pViewSh && pViewSh->GetViewData().GetDocShell() == this)
223 SC_MOD()->InputEnterHandler();
224}
225
227{
228 SCTAB nTab = 0;
230 if (pSh)
231 {
232 const ScMarkData& rMark = pSh->GetViewData().GetMarkData();
233 nTab = rMark.GetFirstSelected();
234 }
235 return nTab;
236}
237
239{
240 // get global state like HiddenInformation::DOCUMENTVERSIONS
242
243 if ( nStates & HiddenInformation::RECORDEDCHANGES )
244 {
245 if ( m_pDocument->GetChangeTrack() && m_pDocument->GetChangeTrack()->GetFirst() )
246 nState |= HiddenInformation::RECORDEDCHANGES;
247 }
248 if ( nStates & HiddenInformation::NOTES )
249 {
250 SCTAB nTableCount = m_pDocument->GetTableCount();
251 bool bFound = false;
252 for (SCTAB nTab = 0; nTab < nTableCount && !bFound; ++nTab)
253 {
254 if (m_pDocument->HasTabNotes(nTab)) //TODO:
255 bFound = true;
256 }
257
258 if (bFound)
259 nState |= HiddenInformation::NOTES;
260 }
261
262 return nState;
263}
264
266{
267 m_pDocument->EnableIdle(false);
268
269 // prevent unnecessary broadcasts and updates
270 OSL_ENSURE(m_pModificator == nullptr, "The Modificator should not exist");
271 m_pModificator.reset( new ScDocShellModificator( *this ) );
272
273 m_pDocument->SetImportingXML( true );
274 m_pDocument->EnableExecuteLink( false ); // #i101304# to be safe, prevent nested loading from external references
275 m_pDocument->EnableUndo( false );
276 // prevent unnecessary broadcasts and "half way listeners"
277 m_pDocument->SetInsertingFromOtherDoc( true );
278}
279
281{
282 if (GetCreateMode() != SfxObjectCreateMode::ORGANIZER)
283 {
284 UpdateLinks();
285 // don't prevent establishing of listeners anymore
286 m_pDocument->SetInsertingFromOtherDoc( false );
287 if ( bRet )
288 {
289 ScChartListenerCollection* pChartListener = m_pDocument->GetChartListenerCollection();
290 if (pChartListener)
291 pChartListener->UpdateDirtyCharts();
292
293 // #95582#; set the table names of linked tables to the new path
294 SCTAB nTabCount = m_pDocument->GetTableCount();
295 for (SCTAB i = 0; i < nTabCount; ++i)
296 {
297 if (m_pDocument->IsLinked( i ))
298 {
299 OUString aName;
300 m_pDocument->GetName(i, aName);
301 OUString aLinkTabName = m_pDocument->GetLinkTab(i);
302 sal_Int32 nLinkTabNameLength = aLinkTabName.getLength();
303 sal_Int32 nNameLength = aName.getLength();
304 if (nLinkTabNameLength < nNameLength)
305 {
306
307 // remove the quotes on begin and end of the docname and restore the escaped quotes
308 const sal_Unicode* pNameBuffer = aName.getStr();
309 if ( *pNameBuffer == '\'' && // all docnames have to have a ' character on the first pos
311 {
312 OUStringBuffer aDocURLBuffer;
313 bool bQuote = true; // Document name is always quoted
314 ++pNameBuffer;
315 while ( bQuote && *pNameBuffer )
316 {
317 if ( *pNameBuffer == '\'' && *(pNameBuffer-1) != '\\' )
318 bQuote = false;
319 else if( *pNameBuffer != '\\' || *(pNameBuffer+1) != '\'' )
320 aDocURLBuffer.append(*pNameBuffer); // If escaped quote: only quote in the name
321 ++pNameBuffer;
322 }
323
324 if( *pNameBuffer == SC_COMPILER_FILE_TAB_SEP ) // after the last quote of the docname should be the # char
325 {
326 sal_Int32 nIndex = nNameLength - nLinkTabNameLength;
327 INetURLObject aINetURLObject(aDocURLBuffer);
328 if(aName.match( aLinkTabName, nIndex) &&
329 (aName[nIndex - 1] == '#') && // before the table name should be the # char
330 !aINetURLObject.HasError()) // the docname should be a valid URL
331 {
332 aName = ScGlobal::GetDocTabName( m_pDocument->GetLinkDoc( i ), m_pDocument->GetLinkTab( i ) );
333 m_pDocument->RenameTab(i, aName, true/*bExternalDocument*/);
334 }
335 // else; nothing has to happen, because it is a user given name
336 }
337 // else; nothing has to happen, because it is a user given name
338 }
339 // else; nothing has to happen, because it is a user given name
340 }
341 // else; nothing has to happen, because it is a user given name
342 }
343 }
344
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 = m_pDocument->GetDPCollection();
348 if ( pDPCollection )
349 {
350 size_t nDPCount = pDPCollection->GetCount();
351 for (size_t nDP=0; nDP<nDPCount; ++nDP)
352 {
353 ScDPObject& rDPObj = (*pDPCollection)[nDP];
354 if (rDPObj.GetName().isEmpty())
355 rDPObj.SetName( pDPCollection->CreateNewName() );
356 }
357 }
358 }
359 }
360 else
361 m_pDocument->SetInsertingFromOtherDoc( false );
362
363 m_pDocument->SetImportingXML( false );
364 m_pDocument->EnableExecuteLink( true );
365 m_pDocument->EnableUndo( true );
366 m_bIsEmpty = false;
367
368 if (m_pModificator)
369 {
370 ScDocument::HardRecalcState eRecalcState = m_pDocument->GetHardRecalcState();
371 // Temporarily set hard-recalc to prevent calling
372 // ScFormulaCell::Notify() during destruction of the Modificator which
373 // will set the cells dirty.
374 if (eRecalcState == ScDocument::HardRecalcState::OFF)
376 m_pModificator.reset();
377 m_pDocument->SetHardRecalcState(eRecalcState);
378 }
379 else
380 {
381 OSL_FAIL("The Modificator should exist");
382 }
383
384 m_pDocument->EnableIdle(true);
385}
386
387namespace {
388
389class LoadMediumGuard
390{
391public:
392 explicit LoadMediumGuard(ScDocument* pDoc) :
393 mpDoc(pDoc)
394 {
395 mpDoc->SetLoadingMedium(true);
396 }
397
398 ~LoadMediumGuard()
399 {
400 mpDoc->SetLoadingMedium(false);
401 }
402private:
403 ScDocument* mpDoc;
404};
405
406void processDataStream( ScDocShell& rShell, const sc::ImportPostProcessData& rData )
407{
408 if (!rData.mpDataStream)
409 return;
410
412 if (!r.maRange.IsValid())
413 return;
414
415 // Break the streamed range into the top range and the height limit. A
416 // height limit of 0 means unlimited i.e. the streamed data will go all
417 // the way to the last row.
418
419 ScRange aTopRange = r.maRange;
420 aTopRange.aEnd.SetRow(aTopRange.aStart.Row());
421 sal_Int32 nLimit = r.maRange.aEnd.Row() - r.maRange.aStart.Row() + 1;
422 if (r.maRange.aEnd.Row() == rShell.GetDocument().MaxRow())
423 // Unlimited range.
424 nLimit = 0;
425
429
430 sc::DataStream* pStrm = new sc::DataStream(&rShell, r.maURL, aTopRange, nLimit, eMove, 0);
433 rMgr.setDataStream(pStrm);
434}
435
436class MessageWithCheck : public weld::MessageDialogController
437{
438private:
439 std::unique_ptr<weld::CheckButton> m_xWarningOnBox;
440public:
441 MessageWithCheck(weld::Window *pParent, const OUString& rUIFile, const OString& rDialogId)
442 : MessageDialogController(pParent, rUIFile, rDialogId, "ask")
443 , m_xWarningOnBox(m_xBuilder->weld_check_button("ask"))
444 {
445 }
446 bool get_active() const { return m_xWarningOnBox->get_active(); }
447 void hide_ask() const { m_xWarningOnBox->set_visible(false); };
448};
449
450#if HAVE_FEATURE_SCRIPTING
451class VBAScriptListener : public ::cppu::WeakImplHelper< css::script::vba::XVBAScriptListener >
452{
453private:
454 ScDocShell* m_pDocSh;
455public:
456 VBAScriptListener(ScDocShell* pDocSh) : m_pDocSh(pDocSh)
457 {
458 }
459
460 // XVBAScriptListener
461 virtual void SAL_CALL notifyVBAScriptEvent( const ::css::script::vba::VBAScriptEvent& aEvent ) override
462 {
463 if (aEvent.Identifier == script::vba::VBAScriptEventId::SCRIPT_STOPPED &&
464 m_pDocSh->GetClipData().is())
465 {
466 m_pDocSh->SetClipData(uno::Reference<datatransfer::XTransferable2>());
467 }
468 }
469
470 // XEventListener
471 virtual void SAL_CALL disposing( const ::css::lang::EventObject& /*Source*/ ) override
472 {
473 }
474};
475#endif
476
477}
478
479bool ScDocShell::LoadXML( SfxMedium* pLoadMedium, const css::uno::Reference< css::embed::XStorage >& xStor )
480{
481 LoadMediumGuard aLoadGuard(m_pDocument.get());
482
483 // MacroCallMode is no longer needed, state is kept in SfxObjectShell now
484
485 // no Seek(0) here - always loading from storage, GetInStream must not be called
486
488
489 ScXMLImportWrapper aImport(*this, pLoadMedium, xStor);
490
491 bool bRet = false;
492 ErrCode nError = ERRCODE_NONE;
493 m_pDocument->LockAdjustHeight();
494 if (GetCreateMode() == SfxObjectCreateMode::ORGANIZER)
495 bRet = aImport.Import(ImportFlags::Styles, nError);
496 else
497 bRet = aImport.Import(ImportFlags::All, nError);
498
499 if ( nError )
500 pLoadMedium->SetError(nError);
501
502 processDataStream(*this, aImport.GetImportPostProcessData());
503
504 //if the document was not generated by LibreOffice, do hard recalc in case some other document
505 //generator saved cached formula results that differ from LibreOffice's calculated results or
506 //did not use cached formula results.
507 uno::Reference<document::XDocumentProperties> xDocProps = GetModel()->getDocumentProperties();
508
509 ScRecalcOptions nRecalcMode =
510 static_cast<ScRecalcOptions>(officecfg::Office::Calc::Formula::Load::ODFRecalcMode::get());
511
512 bool bHardRecalc = false;
513 if (nRecalcMode == RECALC_ASK)
514 {
515 OUString sProductName(utl::ConfigManager::getProductName());
516 if (m_pDocument->IsUserInteractionEnabled() && xDocProps->getGenerator().indexOf(sProductName) == -1)
517 {
518 // Generator is not LibreOffice. Ask if the user wants to perform
519 // full re-calculation.
520 MessageWithCheck aQueryBox(GetActiveDialogParent(),
521 "modules/scalc/ui/recalcquerydialog.ui", "RecalcQueryDialog");
522 aQueryBox.set_primary_text(ScResId(STR_QUERY_FORMULA_RECALC_ONLOAD_ODS));
523 aQueryBox.set_default_response(RET_YES);
524
525 if ( officecfg::Office::Calc::Formula::Load::OOXMLRecalcMode::isReadOnly() )
526 aQueryBox.hide_ask();
527
528 bHardRecalc = aQueryBox.run() == RET_YES;
529
530 if (aQueryBox.get_active())
531 {
532 // Always perform selected action in the future.
533 std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
534 officecfg::Office::Calc::Formula::Load::ODFRecalcMode::set(sal_Int32(0), batch);
535 ScFormulaOptions aOpt = SC_MOD()->GetFormulaOptions();
536 aOpt.SetODFRecalcOptions(bHardRecalc ? RECALC_ALWAYS : RECALC_NEVER);
537 /* XXX is this really supposed to set the ScModule options?
538 * Not the ScDocShell options? */
539 SC_MOD()->SetFormulaOptions(aOpt);
540
541 batch->commit();
542 }
543 }
544 }
545 else if (nRecalcMode == RECALC_ALWAYS)
546 bHardRecalc = true;
547
548 if (bHardRecalc)
549 DoHardRecalc();
550 else
551 {
552 // still need to recalc volatile formula cells.
553 m_pDocument->Broadcast(ScHint(SfxHintId::ScDataChanged, BCA_BRDCST_ALWAYS));
554 }
555
556 AfterXMLLoading(bRet);
557
558 m_pDocument->UnlockAdjustHeight();
559 return bRet;
560}
561
562bool ScDocShell::SaveXML( SfxMedium* pSaveMedium, const css::uno::Reference< css::embed::XStorage >& xStor )
563{
564 m_pDocument->EnableIdle(false);
565
566 ScXMLImportWrapper aImport(*this, pSaveMedium, xStor);
567 bool bRet(false);
568 if (GetCreateMode() != SfxObjectCreateMode::ORGANIZER)
569 bRet = aImport.Export(false);
570 else
571 bRet = aImport.Export(true);
572
573 m_pDocument->EnableIdle(true);
574
575 return bRet;
576}
577
579{
580 LoadMediumGuard aLoadGuard(m_pDocument.get());
581 ScRefreshTimerProtector aProt( m_pDocument->GetRefreshTimerControlAddress() );
582
583 // only the latin script language is loaded
584 // -> initialize the others from options (before loading)
585 InitOptions(true);
586
587 // If this is an ODF file being loaded, then by default, use legacy processing
588 // (if required, it will be overridden in *::ReadUserDataSequence())
589 if (IsOwnStorageFormat(rMedium))
590 {
591 if (ScDrawLayer* pDrawLayer = m_pDocument->GetDrawLayer())
592 {
593 pDrawLayer->SetCompatibilityFlag(SdrCompatibilityFlag::AnchoredTextOverflowLegacy,
594 true); // for tdf#99729
595 pDrawLayer->SetCompatibilityFlag(SdrCompatibilityFlag::LegacySingleLineFontwork,
596 true); // for tdf#148000
597 }
598 }
599
601
602 bool bRet = SfxObjectShell::Load(rMedium);
603 if (bRet)
604 {
605 SetInitialLinkUpdate(&rMedium);
606
607 {
608 // prepare a valid document for XML filter
609 // (for ConvertFrom, InitNew is called before)
610 m_pDocument->MakeTable(0);
611 m_pDocument->GetStyleSheetPool()->CreateStandardStyles();
612 m_pDocument->UpdStlShtPtrsFrmNms();
613
614 /* Create styles that are imported through Orcus */
615
616 OUString aURL("$BRAND_BASE_DIR/" LIBO_SHARE_FOLDER "/calc/styles.xml");
617 rtl::Bootstrap::expandMacros(aURL);
618
619 OUString aPath;
620 osl::FileBase::getSystemPathFromFileURL(aURL, aPath);
621
623
624 if (pOrcus)
625 {
626 pOrcus->importODS_Styles(*m_pDocument, aPath);
627 m_pDocument->GetStyleSheetPool()->setAllParaStandard();
628 }
629
630 bRet = LoadXML( &rMedium, nullptr );
631 }
632 }
633
634 if (!bRet && !rMedium.GetError())
636
637 if (rMedium.GetError())
638 SetError(rMedium.GetError());
639
640 InitItems();
642
643 // invalidate eventually temporary table areas
644 if ( bRet )
645 m_pDocument->InvalidateTableArea();
646
647 m_bIsEmpty = false;
649 return bRet;
650}
651
653{
654 const ScTablesHint* pScHint = dynamic_cast< const ScTablesHint* >( &rHint );
655 if (pScHint)
656 {
657 if (pScHint->GetTablesHintId() == SC_TAB_INSERTED)
658 {
659 uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents = m_pDocument->GetVbaEventProcessor();
660 if ( xVbaEvents.is() ) try
661 {
662 uno::Sequence< uno::Any > aArgs{ uno::Any(pScHint->GetTab1()) };
663 xVbaEvents->processVbaEvent( script::vba::VBAEventId::WORKBOOK_NEWSHEET, aArgs );
664 }
665 catch( uno::Exception& )
666 {
667 }
668 }
669 }
670
671 if ( auto pStyleSheetHint = dynamic_cast<const SfxStyleSheetHint*>(&rHint) ) // Template changed
672 NotifyStyle( *pStyleSheetHint );
673 else if ( auto pStlHint = dynamic_cast<const ScAutoStyleHint*>(&rHint) )
674 {
676
677 // this is called synchronously from ScInterpreter::ScStyle,
678 // modifying the document must be asynchronous
679 // (handled by AddInitial)
680
681 const ScRange& aRange = pStlHint->GetRange();
682 const OUString& aName1 = pStlHint->GetStyle1();
683 const OUString& aName2 = pStlHint->GetStyle2();
684 sal_uInt32 nTimeout = pStlHint->GetTimeout();
685
686 if (!m_pAutoStyleList)
687 m_pAutoStyleList.reset( new ScAutoStyleList(this) );
688 m_pAutoStyleList->AddInitial( aRange, aName1, nTimeout, aName2 );
689 }
690 else if ( auto pEventHint = dynamic_cast<const SfxEventHint*>(&rHint) )
691 {
692 SfxEventHintId nEventId = pEventHint->GetEventId();
693
694 switch ( nEventId )
695 {
696 case SfxEventHintId::LoadFinished:
697 {
698#if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
699 // the readonly documents should not be opened in shared mode
700 if ( HasSharedXMLFlagSet() && !SC_MOD()->IsInSharedDocLoading() && !IsReadOnly() )
701 {
702 if ( SwitchToShared( true, false ) )
703 {
704 ScViewData* pViewData = GetViewData();
705 ScTabView* pTabView = ( pViewData ? pViewData->GetView() : nullptr );
706 if ( pTabView )
707 {
708 pTabView->UpdateLayerLocks();
709 }
710 }
711 else
712 {
713 // switching to shared mode has failed, the document should be opened readonly
714 // TODO/LATER: And error message should be shown here probably
716 }
717 }
718#endif
719 }
720 break;
721 case SfxEventHintId::ViewCreated:
722 {
723 #if HAVE_FEATURE_SCRIPTING
724 uno::Reference<script::vba::XVBACompatibility> xVBACompat(GetBasicContainer(), uno::UNO_QUERY);
725 if ( !m_xVBAListener.is() && xVBACompat.is() )
726 {
727 m_xVBAListener.set(new VBAScriptListener(this));
728 xVBACompat->addVBAScriptListener(m_xVBAListener);
729 }
730#endif
731
732#if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
733 if ( IsDocShared() && !SC_MOD()->IsInSharedDocLoading()
735 {
736 ScAppOptions aAppOptions = SC_MOD()->GetAppOptions();
737 if ( aAppOptions.GetShowSharedDocumentWarning() )
738 {
739 MessageWithCheck aWarningBox(ScDocShell::GetActiveDialogParent(),
740 "modules/scalc/ui/sharedwarningdialog.ui", "SharedWarningDialog");
741 aWarningBox.run();
742
743 bool bChecked = aWarningBox.get_active();
744 if (bChecked)
745 {
746 aAppOptions.SetShowSharedDocumentWarning(false);
747 SC_MOD()->SetAppOptions( aAppOptions );
748 }
749 }
750 }
751#endif
752 try
753 {
754 uno::Reference< uno::XComponentContext > xContext(
756 uno::Reference< lang::XMultiServiceFactory > xServiceManager(
757 xContext->getServiceManager(),
758 uno::UNO_QUERY_THROW );
759 uno::Reference< container::XContentEnumerationAccess > xEnumAccess( xServiceManager, uno::UNO_QUERY_THROW );
760 uno::Reference< container::XEnumeration> xEnum = xEnumAccess->createContentEnumeration(
761 "com.sun.star.sheet.SpreadsheetDocumentJob" );
762 if ( xEnum.is() )
763 {
764 while ( xEnum->hasMoreElements() )
765 {
766 uno::Any aAny = xEnum->nextElement();
767 uno::Reference< lang::XSingleComponentFactory > xFactory;
768 aAny >>= xFactory;
769 if ( xFactory.is() )
770 {
771 uno::Reference< task::XJob > xJob( xFactory->createInstanceWithContext( xContext ), uno::UNO_QUERY_THROW );
772 ScViewData* pViewData = GetViewData();
773 SfxViewShell* pViewShell = ( pViewData ? pViewData->GetViewShell() : nullptr );
774 SfxViewFrame* pViewFrame = ( pViewShell ? &pViewShell->GetViewFrame() : nullptr );
775 SfxFrame* pFrame = ( pViewFrame ? &pViewFrame->GetFrame() : nullptr );
776 uno::Reference< frame::XController > xController = ( pFrame ? pFrame->GetController() : nullptr );
777 uno::Reference< sheet::XSpreadsheetView > xSpreadsheetView( xController, uno::UNO_QUERY_THROW );
778 uno::Sequence< beans::NamedValue > aArgsForJob { { "SpreadsheetView", uno::Any( xSpreadsheetView ) } };
779 xJob->execute( aArgsForJob );
780 }
781 }
782 }
783 }
784 catch ( uno::Exception & )
785 {
786 }
787 }
788 break;
789 case SfxEventHintId::SaveDoc:
790 {
791#if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
792 if ( IsDocShared() && !SC_MOD()->IsInSharedDocSaving() )
793 {
794 bool bSuccess = false;
795 bool bRetry = true;
796 while ( bRetry )
797 {
798 bRetry = false;
799 uno::Reference< frame::XModel > xModel;
800 try
801 {
802 // load shared file
803 xModel.set( LoadSharedDocument(), uno::UNO_SET_THROW );
804 uno::Reference< util::XCloseable > xCloseable( xModel, uno::UNO_QUERY_THROW );
805
806 // check if shared flag is set in shared file
807 bool bShared = false;
808 ScModelObj* pDocObj = comphelper::getFromUnoTunnel<ScModelObj>( xModel );
809 ScDocShell* pSharedDocShell = ( pDocObj ? dynamic_cast< ScDocShell* >( pDocObj->GetObjectShell() ) : nullptr );
810 if ( pSharedDocShell )
811 {
812 bShared = pSharedDocShell->HasSharedXMLFlagSet();
813 }
814
815 // #i87870# check if shared status was disabled and enabled again
816 bool bOwnEntry = false;
817 bool bEntriesNotAccessible = false;
818 try
819 {
821 bOwnEntry = aControlFile.HasOwnEntry();
822 }
823 catch ( uno::Exception& )
824 {
825 bEntriesNotAccessible = true;
826 }
827
828 if ( bShared && bOwnEntry )
829 {
830 uno::Reference< frame::XStorable > xStorable( xModel, uno::UNO_QUERY_THROW );
831
832 if ( xStorable->isReadonly() )
833 {
834 xCloseable->close( true );
835
836 OUString aUserName( ScResId( STR_UNKNOWN_USER ) );
837 bool bNoLockAccess = false;
838 try
839 {
841 LockFileEntry aData = aLockFile.GetLockData();
842 if ( !aData[LockFileComponent::OOOUSERNAME].isEmpty() )
843 {
844 aUserName = aData[LockFileComponent::OOOUSERNAME];
845 }
846 else if ( !aData[LockFileComponent::SYSUSERNAME].isEmpty() )
847 {
848 aUserName = aData[LockFileComponent::SYSUSERNAME];
849 }
850 }
851 catch ( uno::Exception& )
852 {
853 bNoLockAccess = true;
854 }
855
856 if ( bNoLockAccess )
857 {
858 // TODO/LATER: in future an error regarding impossibility to open file for writing could be shown
860 }
861 else
862 {
863 OUString aMessage( ScResId( STR_FILE_LOCKED_SAVE_LATER ) );
864 aMessage = aMessage.replaceFirst( "%1", aUserName );
865
866 std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(GetActiveDialogParent(),
867 VclMessageType::Warning, VclButtonsType::NONE,
868 aMessage));
869 xWarn->add_button(GetStandardText(StandardButtonType::Retry), RET_RETRY);
870 xWarn->add_button(GetStandardText(StandardButtonType::Cancel), RET_CANCEL);
871 xWarn->set_default_response(RET_RETRY);
872 if (xWarn->run() == RET_RETRY)
873 {
874 bRetry = true;
875 }
876 }
877 }
878 else
879 {
880 // merge changes from shared file into temp file
881 bool bSaveToShared = false;
882 if ( pSharedDocShell )
883 {
884 bSaveToShared = MergeSharedDocument( pSharedDocShell );
885 }
886
887 // close shared file
888 xCloseable->close( true );
889
890 // TODO: keep file lock on shared file
891
892 // store to shared file
893 if ( bSaveToShared )
894 {
895 bool bChangedViewSettings = false;
896 ScChangeViewSettings* pChangeViewSet = m_pDocument->GetChangeViewSettings();
897 if ( pChangeViewSet && pChangeViewSet->ShowChanges() )
898 {
899 pChangeViewSet->SetShowChanges( false );
900 pChangeViewSet->SetShowAccepted( false );
901 m_pDocument->SetChangeViewSettings( *pChangeViewSet );
902 bChangedViewSettings = true;
903 }
904
905 // TODO/LATER: More entries from the MediaDescriptor might be interesting for the merge
906 uno::Sequence< beans::PropertyValue > aValues{
908 "FilterName",
909 GetMedium()->GetFilter()->GetFilterName())
910 };
911
912 const SfxStringItem* pPasswordItem = SfxItemSet::GetItem<SfxStringItem>(GetMedium()->GetItemSet(), SID_PASSWORD, false);
913 if ( pPasswordItem && !pPasswordItem->GetValue().isEmpty() )
914 {
915 aValues.realloc( 2 );
916 auto pValues = aValues.getArray();
917 pValues[1].Name = "Password";
918 pValues[1].Value <<= pPasswordItem->GetValue();
919 }
920 const SfxUnoAnyItem* pEncryptionItem = SfxItemSet::GetItem<SfxUnoAnyItem>(GetMedium()->GetItemSet(), SID_ENCRYPTIONDATA, false);
921 if (pEncryptionItem)
922 {
923 aValues.realloc(aValues.getLength() + 1);
924 auto pValues = aValues.getArray();
925 pValues[aValues.getLength() - 1].Name = "EncryptionData";
926 pValues[aValues.getLength() - 1].Value = pEncryptionItem->GetValue();
927 }
928
929 SC_MOD()->SetInSharedDocSaving( true );
930 GetModel()->storeToURL( GetSharedFileURL(), aValues );
931 SC_MOD()->SetInSharedDocSaving( false );
932
933 if ( bChangedViewSettings )
934 {
935 pChangeViewSet->SetShowChanges( true );
936 pChangeViewSet->SetShowAccepted( true );
937 m_pDocument->SetChangeViewSettings( *pChangeViewSet );
938 }
939 }
940
941 bSuccess = true;
943 }
944 }
945 else
946 {
947 xCloseable->close( true );
948
949 if ( bEntriesNotAccessible )
950 {
951 // TODO/LATER: in future an error regarding impossibility to write to share control file could be shown
953 }
954 else
955 {
956 std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(GetActiveDialogParent(),
957 VclMessageType::Warning, VclButtonsType::Ok,
958 ScResId(STR_DOC_NOLONGERSHARED)));
959 xWarn->run();
960
961 SfxBindings* pBindings = GetViewBindings();
962 if ( pBindings )
963 {
964 pBindings->ExecuteSynchron( SID_SAVEASDOC );
965 }
966 }
967 }
968 }
969 catch ( uno::Exception& )
970 {
971 TOOLS_WARN_EXCEPTION( "sc", "SfxEventHintId::SaveDoc" );
972 SC_MOD()->SetInSharedDocSaving( false );
973
974 try
975 {
976 uno::Reference< util::XCloseable > xClose( xModel, uno::UNO_QUERY_THROW );
977 xClose->close( true );
978 }
979 catch ( uno::Exception& )
980 {
981 }
982 }
983 }
984
985 if ( !bSuccess )
986 SetError(ERRCODE_IO_ABORT); // this error code will produce no error message, but will break the further saving process
987 }
988#endif
989
991 m_pSheetSaveData->SetInSupportedSave(true);
992 }
993 break;
994 case SfxEventHintId::SaveAsDoc:
995 {
996 if ( GetDocument().GetExternalRefManager()->containsUnsavedReferences() )
997 {
998 std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(GetActiveDialogParent(),
999 VclMessageType::Warning, VclButtonsType::YesNo,
1000 ScResId(STR_UNSAVED_EXT_REF)));
1001 if (RET_NO == xWarn->run())
1002 {
1003 SetError(ERRCODE_IO_ABORT); // this error code will produce no error message, but will break the further saving process
1004 }
1005 }
1006 [[fallthrough]];
1007 }
1008 case SfxEventHintId::SaveToDoc:
1009 // #i108978# If no event is sent before saving, there will also be no "...DONE" event,
1010 // and SAVE/SAVEAS can't be distinguished from SAVETO. So stream copying is only enabled
1011 // if there is a SAVE/SAVEAS/SAVETO event first.
1012 if (m_pSheetSaveData)
1013 m_pSheetSaveData->SetInSupportedSave(true);
1014 break;
1015 case SfxEventHintId::SaveDocDone:
1016 case SfxEventHintId::SaveAsDocDone:
1017 {
1018 // new positions are used after "save" and "save as", but not "save to"
1019 UseSheetSaveEntries(); // use positions from saved file for next saving
1020 [[fallthrough]];
1021 }
1022 case SfxEventHintId::SaveToDocDone:
1023 // only reset the flag, don't use the new positions
1024 if (m_pSheetSaveData)
1025 m_pSheetSaveData->SetInSupportedSave(false);
1026 break;
1027 default:
1028 {
1029 }
1030 break;
1031 }
1032 }
1033 else if (rHint.GetId() == SfxHintId::TitleChanged) // Without parameter
1034 {
1035 m_pDocument->SetName( SfxShell::GetName() );
1036 // RegisterNewTargetNames doesn't exist any longer
1037 SfxGetpApp()->Broadcast(SfxHint( SfxHintId::ScDocNameChanged )); // Navigator
1038 }
1039 else if (rHint.GetId() == SfxHintId::Deinitializing)
1040 {
1041
1042#if HAVE_FEATURE_SCRIPTING
1043 uno::Reference<script::vba::XVBACompatibility> xVBACompat(GetBasicContainer(), uno::UNO_QUERY);
1044 if (m_xVBAListener.is() && xVBACompat.is())
1045 {
1046 xVBACompat->removeVBAScriptListener(m_xVBAListener);
1047 }
1048#endif
1049
1050 if (m_pDocument->IsClipboardSource())
1051 {
1052 // Notes copied to the clipboard have a raw SdrCaptionObj pointer
1053 // copied from this document, forget it as it references this
1054 // document's drawing layer pages and what not, which otherwise when
1055 // pasting to another document after this document was destructed would
1056 // attempt to access non-existing data. Preserve the text data though.
1057 ScDocument* pClipDoc = ScModule::GetClipDoc();
1058 if (pClipDoc)
1059 pClipDoc->ClosingClipboardSource();
1060 }
1061 }
1062
1063 const SfxEventHint* pSfxEventHint = dynamic_cast<const SfxEventHint*>(&rHint);
1064 if (!pSfxEventHint)
1065 return;
1066
1067 switch( pSfxEventHint->GetEventId() )
1068 {
1069 case SfxEventHintId::CreateDoc:
1070 {
1071 uno::Any aWorkbook;
1072 aWorkbook <<= mxAutomationWorkbookObject;
1073 uno::Sequence< uno::Any > aArgs{ aWorkbook };
1074 SC_MOD()->CallAutomationApplicationEventSinks( "NewWorkbook", aArgs );
1075 }
1076 break;
1077 case SfxEventHintId::OpenDoc:
1078 {
1079 uno::Any aWorkbook;
1080 aWorkbook <<= mxAutomationWorkbookObject;
1081 uno::Sequence< uno::Any > aArgs{ aWorkbook };
1082 SC_MOD()->CallAutomationApplicationEventSinks( "WorkbookOpen", aArgs );
1083 }
1084 break;
1085 default:
1086 break;
1087 }
1088}
1089
1090// Load contents for organizer
1092{
1093 LoadMediumGuard aLoadGuard(m_pDocument.get());
1094 ScRefreshTimerProtector aProt( m_pDocument->GetRefreshTimerControlAddress() );
1095
1097
1098 bool bRet = false;
1099
1100 SetInitialLinkUpdate(&rMedium);
1101
1102 // until loading/saving only the styles in XML is implemented,
1103 // load the whole file
1104 bRet = LoadXML( &rMedium, nullptr );
1105 InitItems();
1106
1107 SfxObjectShell::LoadFrom( rMedium );
1108
1109 return bRet;
1110}
1111
1112static void lcl_parseHtmlFilterOption(const OUString& rOption, LanguageType& rLang, bool& rDateConvert)
1113{
1114 OUStringBuffer aBuf;
1115 std::vector< OUString > aTokens;
1116 sal_Int32 n = rOption.getLength();
1117 const sal_Unicode* p = rOption.getStr();
1118 for (sal_Int32 i = 0; i < n; ++i)
1119 {
1120 const sal_Unicode c = p[i];
1121 if (c == ' ')
1122 {
1123 if (!aBuf.isEmpty())
1124 aTokens.push_back( aBuf.makeStringAndClear() );
1125 }
1126 else
1127 aBuf.append(c);
1128 }
1129
1130 if (!aBuf.isEmpty())
1131 aTokens.push_back( aBuf.makeStringAndClear() );
1132
1133 rLang = LanguageType( 0 );
1134 rDateConvert = false;
1135
1136 if (!aTokens.empty())
1137 rLang = static_cast<LanguageType>(aTokens[0].toInt32());
1138 if (aTokens.size() > 1)
1139 rDateConvert = static_cast<bool>(aTokens[1].toInt32());
1140}
1141
1143{
1144 LoadMediumGuard aLoadGuard(m_pDocument.get());
1145
1146 bool bRet = false; // sal_False means user quit!
1147 // On error: Set error at stream
1148
1149 ScRefreshTimerProtector aProt( m_pDocument->GetRefreshTimerControlAddress() );
1150
1151 GetUndoManager()->Clear();
1152
1153 // Set optimal col width after import?
1154 bool bSetColWidths = false;
1155 bool bSetSimpleTextColWidths = false;
1156 std::map<SCCOL, ScColWidthParam> aColWidthParam;
1157 ScRange aColWidthRange;
1158 // Set optimal row height after import?
1159 bool bSetRowHeights = false;
1160
1161 vector<ScDocRowHeightUpdater::TabRanges> aRecalcRowRangesArray;
1162
1163 // All filters need the complete file in one piece (not asynchronously)
1164 // So make sure that we transfer the whole file with CreateFileStream
1165 rMedium.GetPhysicalName();
1166
1167 SetInitialLinkUpdate(&rMedium);
1168
1169 std::shared_ptr<const SfxFilter> pFilter = rMedium.GetFilter();
1170 if (pFilter)
1171 {
1172 OUString aFltName = pFilter->GetFilterName();
1173
1174 bool bCalc3 = aFltName == "StarCalc 3.0";
1175 bool bCalc4 = aFltName == "StarCalc 4.0";
1176 if (!bCalc3 && !bCalc4)
1177 m_pDocument->SetInsertingFromOtherDoc( true );
1178
1179 if (aFltName == pFilterXML)
1180 bRet = LoadXML( &rMedium, nullptr );
1181 else if (aFltName == pFilterLotus)
1182 {
1183 OUString sItStr;
1184 SfxItemSet* pSet = rMedium.GetItemSet();
1185 const SfxStringItem* pOptionsItem;
1186 if ( pSet &&
1187 (pOptionsItem = pSet->GetItemIfSet( SID_FILE_FILTEROPTIONS, true )) )
1188 {
1189 sItStr = pOptionsItem->GetValue();
1190 }
1191
1192 if (sItStr.isEmpty())
1193 {
1194 // default for lotus import (from API without options):
1195 // IBM_437 encoding
1196 sItStr = ScGlobal::GetCharsetString( RTL_TEXTENCODING_IBM_437 );
1197 }
1198
1201 if (eError != ERRCODE_NONE)
1202 {
1203 if (!GetError())
1204 SetError(eError);
1205
1206 if( eError.IsWarning() )
1207 bRet = true;
1208 }
1209 else
1210 bRet = true;
1211 bSetColWidths = true;
1212 bSetRowHeights = true;
1213 }
1214 else if ( aFltName == pFilterExcel4 || aFltName == pFilterExcel5 ||
1215 aFltName == pFilterExcel95 || aFltName == pFilterExcel97 ||
1216 aFltName == pFilterEx4Temp || aFltName == pFilterEx5Temp ||
1217 aFltName == pFilterEx95Temp || aFltName == pFilterEx97Temp )
1218 {
1219 EXCIMPFORMAT eFormat = EIF_AUTO;
1220 if ( aFltName == pFilterExcel4 || aFltName == pFilterEx4Temp )
1221 eFormat = EIF_BIFF_LE4;
1222 else if ( aFltName == pFilterExcel5 || aFltName == pFilterExcel95 ||
1223 aFltName == pFilterEx5Temp || aFltName == pFilterEx95Temp )
1224 eFormat = EIF_BIFF5;
1225 else if ( aFltName == pFilterExcel97 || aFltName == pFilterEx97Temp )
1226 eFormat = EIF_BIFF8;
1227
1228 MakeDrawLayer();
1229 CalcOutputFactor(); // prepare update of row height
1230 ErrCode eError = ScFormatFilter::Get().ScImportExcel( rMedium, m_pDocument.get(), eFormat );
1231 m_pDocument->UpdateFontCharSet();
1232 if ( m_pDocument->IsChartListenerCollectionNeedsUpdate() )
1233 m_pDocument->UpdateChartListenerCollection();
1234
1235 // all graphics objects must have names
1236 m_pDocument->EnsureGraphicNames();
1237
1238 if (eError != ERRCODE_NONE)
1239 {
1240 if (!GetError())
1241 SetError(eError);
1242 if( eError.IsWarning() )
1243 bRet = true;
1244 }
1245 else
1246 bRet = true;
1247 }
1248 else if (aFltName == "Gnumeric Spreadsheet")
1249 {
1251 if (!pOrcus)
1252 return false;
1253
1254 bRet = pOrcus->importGnumeric(*m_pDocument, rMedium);
1255 }
1256 else if (aFltName == "MS Excel 2003 XML Orcus")
1257 {
1259 if (!pOrcus)
1260 return false;
1261
1262 bRet = pOrcus->importExcel2003XML(*m_pDocument, rMedium);
1263 }
1264 else if (aFltName == SC_TEXT_CSV_FILTER_NAME)
1265 {
1266 SfxItemSet* pSet = rMedium.GetItemSet();
1267 const SfxStringItem* pOptionsItem;
1268 ScAsciiOptions aOptions;
1269 bool bOptInit = false;
1270
1271 if ( pSet &&
1272 (pOptionsItem = pSet->GetItemIfSet( SID_FILE_FILTEROPTIONS )) )
1273 {
1274 aOptions.ReadFromString( pOptionsItem->GetValue() );
1275 bOptInit = true;
1276 }
1277
1278 if ( !bOptInit )
1279 {
1280 // default for ascii import (from API without options):
1281 // UTF-8 encoding, comma, double quotes
1282
1283 aOptions.SetCharSet(RTL_TEXTENCODING_UTF8);
1284 aOptions.SetFieldSeps( OUString(',') );
1285 aOptions.SetTextSep( '"' );
1286 }
1287
1288 ErrCode eError = ERRCODE_NONE;
1289 bool bOverflowRow, bOverflowCol, bOverflowCell;
1290 bOverflowRow = bOverflowCol = bOverflowCell = false;
1291
1292 if( ! rMedium.IsStorage() )
1293 {
1294 ScImportExport aImpEx( *m_pDocument );
1295 aImpEx.SetExtOptions( aOptions );
1296
1297 SvStream* pInStream = rMedium.GetInStream();
1298 if (pInStream)
1299 {
1300 pInStream->SetStreamCharSet( aOptions.GetCharSet() );
1301 pInStream->Seek( 0 );
1302 bRet = aImpEx.ImportStream( *pInStream, rMedium.GetBaseURL(), SotClipboardFormatId::STRING );
1303 eError = bRet ? ERRCODE_NONE : SCERR_IMPORT_CONNECT;
1304 m_pDocument->StartAllListeners();
1306 m_pDocument->SetAllFormulasDirty(aCxt);
1307
1308 // tdf#82254 - check whether to include a byte-order-mark in the output
1309 if (const bool bIncludeBOM = aImpEx.GetIncludeBOM())
1310 {
1311 aOptions.SetIncludeBOM(bIncludeBOM);
1312 if (rMedium.GetItemSet() != nullptr)
1313 rMedium.GetItemSet()->Put(
1314 SfxStringItem(SID_FILE_FILTEROPTIONS, aOptions.WriteToString()));
1315 }
1316
1317 // for mobile case, we use a copy of the original document and give it a temporary name before editing
1318 // Therefore, the sheet name becomes ugly, long and nonsensical.
1319#if !(defined ANDROID)
1320 // The same resulting name has to be handled in
1321 // ScExternalRefCache::initializeDoc() and related, hence
1322 // pass 'true' for RenameTab()'s bExternalDocument for a
1323 // composed name so ValidTabName() will not be checked,
1324 // which could veto the rename in case it contained
1325 // characters that Excel does not handle. If we wanted to
1326 // change that then it needed to be handled in all
1327 // corresponding places of the external references
1328 // manager/cache. Likely then we'd also need a method to
1329 // compose a name excluding such characters.
1330 m_pDocument->RenameTab( 0, INetURLObject( rMedium.GetName()).GetBase(), true/*bExternalDocument*/);
1331#endif
1332 bOverflowRow = aImpEx.IsOverflowRow();
1333 bOverflowCol = aImpEx.IsOverflowCol();
1334 bOverflowCell = aImpEx.IsOverflowCell();
1335 }
1336 else
1337 {
1338 OSL_FAIL( "No Stream" );
1339 }
1340 }
1341
1342 if (eError != ERRCODE_NONE)
1343 {
1344 if (!GetError())
1345 SetError(eError);
1346 if( eError.IsWarning() )
1347 bRet = true;
1348 }
1349 else if (!GetError() && (bOverflowRow || bOverflowCol || bOverflowCell))
1350 {
1351 // precedence: row, column, cell
1352 ErrCode nWarn = (bOverflowRow ? SCWARN_IMPORT_ROW_OVERFLOW :
1353 (bOverflowCol ? SCWARN_IMPORT_COLUMN_OVERFLOW :
1355 SetError(nWarn);
1356 }
1357 bSetColWidths = true;
1358 bSetSimpleTextColWidths = true;
1359 }
1360 else if (aFltName == pFilterDBase)
1361 {
1362 OUString sItStr;
1363 SfxItemSet* pSet = rMedium.GetItemSet();
1364 const SfxStringItem* pOptionsItem;
1365 if ( pSet &&
1366 (pOptionsItem = pSet->GetItemIfSet( SID_FILE_FILTEROPTIONS )) )
1367 {
1368 sItStr = pOptionsItem->GetValue();
1369 }
1370
1371 if (sItStr.isEmpty())
1372 {
1373 // default for dBase import (from API without options):
1374 // IBM_850 encoding
1375
1376 sItStr = ScGlobal::GetCharsetString( RTL_TEXTENCODING_IBM_850 );
1377 }
1378
1379 ScDocRowHeightUpdater::TabRanges aRecalcRanges(0, m_pDocument->MaxRow());
1380 ErrCode eError = DBaseImport( rMedium.GetPhysicalName(),
1381 ScGlobal::GetCharsetValue(sItStr), aColWidthParam, aRecalcRanges.maRanges );
1382 aRecalcRowRangesArray.push_back(aRecalcRanges);
1383
1384 if (eError != ERRCODE_NONE)
1385 {
1386 if (!GetError())
1387 SetError(eError);
1388 if( eError.IsWarning() )
1389 bRet = true;
1390 }
1391 else
1392 bRet = true;
1393
1394 aColWidthRange.aStart.SetRow( 1 ); // Except for the column header
1395 bSetColWidths = true;
1396 bSetSimpleTextColWidths = true;
1397 }
1398 else if (aFltName == pFilterDif)
1399 {
1400 SvStream* pStream = rMedium.GetInStream();
1401 if (pStream)
1402 {
1403 ErrCode eError;
1404 OUString sItStr;
1405 SfxItemSet* pSet = rMedium.GetItemSet();
1406 const SfxStringItem* pOptionsItem;
1407 if ( pSet &&
1408 (pOptionsItem = pSet->GetItemIfSet( SID_FILE_FILTEROPTIONS )) )
1409 {
1410 sItStr = pOptionsItem->GetValue();
1411 }
1412
1413 if (sItStr.isEmpty())
1414 {
1415 // default for DIF import (from API without options):
1416 // ISO8859-1/MS_1252 encoding
1417
1418 sItStr = ScGlobal::GetCharsetString( RTL_TEXTENCODING_MS_1252 );
1419 }
1420
1421 eError = ScFormatFilter::Get().ScImportDif( *pStream, m_pDocument.get(), ScAddress(0,0,0),
1423 if (eError != ERRCODE_NONE)
1424 {
1425 if (!GetError())
1426 SetError(eError);
1427
1428 if( eError.IsWarning() )
1429 bRet = true;
1430 }
1431 else
1432 bRet = true;
1433 }
1434 bSetColWidths = true;
1435 bSetSimpleTextColWidths = true;
1436 bSetRowHeights = true;
1437 }
1438 else if (aFltName == pFilterSylk)
1439 {
1441 bool bOverflowRow, bOverflowCol, bOverflowCell;
1442 bOverflowRow = bOverflowCol = bOverflowCell = false;
1443 if( !rMedium.IsStorage() )
1444 {
1445 ScImportExport aImpEx( *m_pDocument );
1446
1447 SvStream* pInStream = rMedium.GetInStream();
1448 if (pInStream)
1449 {
1450 pInStream->Seek( 0 );
1451 bRet = aImpEx.ImportStream( *pInStream, rMedium.GetBaseURL(), SotClipboardFormatId::SYLK );
1452 eError = bRet ? ERRCODE_NONE : SCERR_IMPORT_UNKNOWN;
1453 m_pDocument->StartAllListeners();
1455 m_pDocument->SetAllFormulasDirty(aCxt);
1456
1457 bOverflowRow = aImpEx.IsOverflowRow();
1458 bOverflowCol = aImpEx.IsOverflowCol();
1459 bOverflowCell = aImpEx.IsOverflowCell();
1460 }
1461 else
1462 {
1463 OSL_FAIL( "No Stream" );
1464 }
1465 }
1466
1467 if (eError != ERRCODE_NONE)
1468 {
1469 if (!GetError())
1470 SetError(eError);
1471 if( eError.IsWarning() )
1472 bRet = true;
1473 }
1474 else if (!GetError() && (bOverflowRow || bOverflowCol || bOverflowCell))
1475 {
1476 // precedence: row, column, cell
1477 ErrCode nWarn = (bOverflowRow ? SCWARN_IMPORT_ROW_OVERFLOW :
1478 (bOverflowCol ? SCWARN_IMPORT_COLUMN_OVERFLOW :
1480 SetError(nWarn);
1481 }
1482 bSetColWidths = true;
1483 bSetSimpleTextColWidths = true;
1484 bSetRowHeights = true;
1485 }
1486 else if (aFltName == pFilterQPro6)
1487 {
1489 if (eError != ERRCODE_NONE)
1490 {
1491 if (!GetError())
1492 SetError(eError);
1493 if( eError.IsWarning() )
1494 bRet = true;
1495 }
1496 else
1497 bRet = true;
1498 // TODO: Filter should set column widths. Not doing it here, it may
1499 // result in very narrow or wide columns, depending on content.
1500 // Setting row heights makes cells with font size attribution or
1501 // wrapping enabled look nicer...
1502 bSetRowHeights = true;
1503 }
1504 else if (aFltName == pFilterRtf)
1505 {
1507 if( !rMedium.IsStorage() )
1508 {
1509 SvStream* pInStream = rMedium.GetInStream();
1510 if (pInStream)
1511 {
1512 pInStream->Seek( 0 );
1513 ScRange aRange;
1514 eError = ScFormatFilter::Get().ScImportRTF( *pInStream, rMedium.GetBaseURL(), m_pDocument.get(), aRange );
1515 if (eError != ERRCODE_NONE)
1516 {
1517 if (!GetError())
1518 SetError(eError);
1519
1520 if( eError.IsWarning() )
1521 bRet = true;
1522 }
1523 else
1524 bRet = true;
1525 m_pDocument->StartAllListeners();
1527 m_pDocument->SetAllFormulasDirty(aCxt);
1528 bSetColWidths = true;
1529 bSetRowHeights = true;
1530 }
1531 else
1532 {
1533 OSL_FAIL( "No Stream" );
1534 }
1535 }
1536
1537 if (eError != ERRCODE_NONE)
1538 {
1539 if (!GetError())
1540 SetError(eError);
1541 if( eError.IsWarning() )
1542 bRet = true;
1543 }
1544 }
1545 else if (aFltName == pFilterHtml || aFltName == pFilterHtmlWebQ)
1546 {
1548 bool bWebQuery = aFltName == pFilterHtmlWebQ;
1549 if( !rMedium.IsStorage() )
1550 {
1551 SvStream* pInStream = rMedium.GetInStream();
1552 if (pInStream)
1553 {
1555 bool bDateConvert = false;
1556 SfxItemSet* pSet = rMedium.GetItemSet();
1557 const SfxStringItem* pOptionsItem;
1558 if ( pSet &&
1559 (pOptionsItem = pSet->GetItemIfSet( SID_FILE_FILTEROPTIONS )) )
1560 {
1561 OUString aFilterOption = pOptionsItem->GetValue();
1562 lcl_parseHtmlFilterOption(aFilterOption, eLang, bDateConvert);
1563 }
1564
1565 pInStream->Seek( 0 );
1566 ScRange aRange;
1567 // HTML does its own ColWidth/RowHeight
1570 eError = ScFormatFilter::Get().ScImportHTML( *pInStream, rMedium.GetBaseURL(), m_pDocument.get(), aRange,
1571 GetOutputFactor(), !bWebQuery, &aNumFormatter, bDateConvert );
1572 if (eError != ERRCODE_NONE)
1573 {
1574 if (!GetError())
1575 SetError(eError);
1576
1577 if( eError.IsWarning() )
1578 bRet = true;
1579 }
1580 else
1581 bRet = true;
1582 m_pDocument->StartAllListeners();
1583
1585 m_pDocument->SetAllFormulasDirty(aCxt);
1586 }
1587 else
1588 {
1589 OSL_FAIL( "No Stream" );
1590 }
1591 }
1592
1593 if (eError != ERRCODE_NONE)
1594 {
1595 if (!GetError())
1596 SetError(eError);
1597 if( eError.IsWarning() )
1598 bRet = true;
1599 }
1600 }
1601 else
1602 {
1603 if (!GetError())
1604 {
1605 SAL_WARN("sc.filter", "No match for filter '" << aFltName << "' in ConvertFrom");
1607 }
1608 }
1609
1610 if (!bCalc3)
1611 m_pDocument->SetInsertingFromOtherDoc( false );
1612 }
1613 else
1614 {
1615 OSL_FAIL("No Filter in ConvertFrom");
1616 }
1617
1618 InitItems();
1620 if ( bRet && (bSetColWidths || bSetRowHeights) )
1621 { // Adjust column width/row height; base 100% zoom
1622 Fraction aZoom( 1, 1 );
1623 double nPPTX = ScGlobal::nScreenPPTX * static_cast<double>(aZoom) / GetOutputFactor(); // Factor is printer display ratio
1624 double nPPTY = ScGlobal::nScreenPPTY * static_cast<double>(aZoom);
1626 // all sheets (for Excel import)
1627 SCTAB nTabCount = m_pDocument->GetTableCount();
1628 for (SCTAB nTab=0; nTab<nTabCount; nTab++)
1629 {
1630 SCCOL nEndCol;
1631 SCROW nEndRow;
1632 m_pDocument->GetCellArea( nTab, nEndCol, nEndRow );
1633 aColWidthRange.aEnd.SetCol( nEndCol );
1634 aColWidthRange.aEnd.SetRow( nEndRow );
1635 ScMarkData aMark(m_pDocument->GetSheetLimits());
1636 aMark.SetMarkArea( aColWidthRange );
1637 aMark.MarkToMulti();
1638
1639 // Order is important: First width, then height
1640 if ( bSetColWidths )
1641 {
1642 for ( SCCOL nCol=0; nCol <= nEndCol; nCol++ )
1643 {
1644 if (!bSetSimpleTextColWidths)
1645 aColWidthParam[nCol].mbSimpleText = false;
1646
1647 sal_uInt16 nWidth = m_pDocument->GetOptimalColWidth(
1648 nCol, nTab, pVirtDev, nPPTX, nPPTY, aZoom, aZoom, false, &aMark,
1649 &aColWidthParam[nCol] );
1650 m_pDocument->SetColWidth( nCol, nTab,
1651 nWidth + static_cast<sal_uInt16>(ScGlobal::nLastColWidthExtra) );
1652 }
1653 }
1654 }
1655
1656 if (bSetRowHeights)
1657 {
1658 // Update all rows in all tables.
1659 ScSizeDeviceProvider aProv(this);
1660 ScDocRowHeightUpdater aUpdater(*m_pDocument, aProv.GetDevice(), aProv.GetPPTX(), aProv.GetPPTY(), nullptr);
1661 aUpdater.update();
1662 }
1663 else if (!aRecalcRowRangesArray.empty())
1664 {
1665 // Update only specified row ranges for better performance.
1666 ScSizeDeviceProvider aProv(this);
1667 ScDocRowHeightUpdater aUpdater(*m_pDocument, aProv.GetDevice(), aProv.GetPPTX(), aProv.GetPPTY(), &aRecalcRowRangesArray);
1668 aUpdater.update();
1669 }
1670 }
1672
1673 // invalidate eventually temporary table areas
1674 if ( bRet )
1675 m_pDocument->InvalidateTableArea();
1676
1677 m_bIsEmpty = false;
1678
1679 return bRet;
1680}
1681
1683{
1684 std::shared_ptr<const SfxFilter> pFilter = rMed.GetFilter();
1685 if (!pFilter)
1686 return false;
1687
1688 if (pFilter->GetProviderName() == "orcus")
1689 {
1691 if (!pOrcus)
1692 return false;
1693
1694 const OUString& rFilterName = pFilter->GetName();
1695 if (rFilterName == "gnumeric")
1696 {
1697 if (!pOrcus->importGnumeric(*m_pDocument, rMed))
1698 return false;
1699 }
1700 else if (rFilterName == "csv")
1701 {
1702 if (!pOrcus->importCSV(*m_pDocument, rMed))
1703 return false;
1704 }
1705 else if (rFilterName == "xlsx")
1706 {
1707 if (!pOrcus->importXLSX(*m_pDocument, rMed))
1708 return false;
1709 }
1710 else if (rFilterName == "ods")
1711 {
1712 if (!pOrcus->importODS(*m_pDocument, rMed))
1713 return false;
1714 }
1715
1717 return true;
1718 }
1719
1720 return false;
1721}
1722
1724 : mrDocShell( rDocShell)
1725{
1726 // DoEnterHandler not here (because of AutoSave), is in ExecuteSave.
1727
1728 ScChartListenerCollection* pCharts = mrDocShell.m_pDocument->GetChartListenerCollection();
1729 if (pCharts)
1730 pCharts->UpdateDirtyCharts(); // Charts to be updated.
1731 mrDocShell.m_pDocument->StopTemporaryChartLock();
1733 mrDocShell.m_pAutoStyleList->ExecuteAllNow(); // Execute template timeouts now.
1734 if (mrDocShell.m_pDocument->HasExternalRefManager())
1735 {
1736 ScExternalRefManager* pRefMgr = mrDocShell.m_pDocument->GetExternalRefManager();
1737 if (pRefMgr && pRefMgr->hasExternalData())
1738 {
1739 pRefMgr->setAllCacheTableReferencedStati( false);
1740 mrDocShell.m_pDocument->MarkUsedExternalReferences(); // Mark tables of external references to be written.
1741 }
1742 }
1743 if (mrDocShell.GetCreateMode()== SfxObjectCreateMode::STANDARD)
1744 mrDocShell.SfxObjectShell::SetVisArea( tools::Rectangle() ); // "Normally" worked on => no VisArea.
1745}
1746
1748{
1749 if (mrDocShell.m_pDocument->HasExternalRefManager())
1750 {
1751 ScExternalRefManager* pRefMgr = mrDocShell.m_pDocument->GetExternalRefManager();
1752 if (pRefMgr && pRefMgr->hasExternalData())
1753 {
1754 // Prevent accidental data loss due to lack of knowledge.
1755 pRefMgr->setAllCacheTableReferencedStati( true);
1756 }
1757 }
1758}
1759
1761{
1762 ScRefreshTimerProtector aProt( m_pDocument->GetRefreshTimerControlAddress() );
1763
1764 PrepareSaveGuard aPrepareGuard( *this);
1765
1766 if (const auto pFrame1 = SfxViewFrame::GetFirst(this))
1767 {
1768 if (auto pSysWin = pFrame1->GetWindow().GetSystemWindow())
1769 {
1770 pSysWin->SetAccessibleName(OUString());
1771 }
1772 }
1773 // wait cursor is handled with progress bar
1774 bool bRet = SfxObjectShell::Save();
1775 if( bRet )
1776 bRet = SaveXML( GetMedium(), nullptr );
1777 return bRet;
1778}
1779
1780namespace {
1781
1785void popFileName(OUString& rPath)
1786{
1787 if (!rPath.isEmpty())
1788 {
1789 INetURLObject aURLObj(rPath);
1790 aURLObj.removeSegment();
1791 rPath = aURLObj.GetMainURL(INetURLObject::DecodeMechanism::NONE);
1792 }
1793}
1794
1795}
1796
1798{
1799 // Commit any cell changes before saving.
1800 SC_MOD()->InputEnterHandler();
1801}
1802
1804{
1805 OUString aCurPath; // empty for new document that hasn't been saved.
1806 const SfxMedium* pCurMedium = GetMedium();
1807 if (pCurMedium)
1808 {
1809 aCurPath = pCurMedium->GetName();
1810 popFileName(aCurPath);
1811 }
1812
1813 if (!aCurPath.isEmpty())
1814 {
1815 // current document has a path -> not a brand-new document.
1816 OUString aNewPath = rMedium.GetName();
1817 popFileName(aNewPath);
1818 OUString aRel = URIHelper::simpleNormalizedMakeRelative(aCurPath, aNewPath);
1819 if (!aRel.isEmpty())
1820 {
1821 // Directory path will change before and after the save.
1822 m_pDocument->InvalidateStreamOnSave();
1823 }
1824 }
1825
1826 ScTabViewShell* pViewShell = GetBestViewShell();
1828 if (bNeedsRehash)
1829 // legacy xls hash double-hashed by SHA1 is also supported.
1831 if (bNeedsRehash)
1832 { // SHA256 explicitly supported in ODF 1.2, implicitly in ODF 1.1
1834 }
1835
1836 // skip saving recovery file instead of showing re-type password dialog window
1837 if ( bNeedsRehash && rMedium.GetFilter()->GetFilterName() == "calc8" &&
1838 // it seems, utl::MediaDescriptor::PROP_AUTOSAVEEVENT is true at Save As, too,
1839 // so check the backup path
1840 rMedium.GetName().startsWith( SvtPathOptions().GetBackupPath() ) )
1841 {
1842 SAL_WARN("sc.filter", "Should re-type password for own format, won't export recovery file");
1844 return false;
1845 }
1846
1847 if (pViewShell && bNeedsRehash)
1848 {
1849 if (!pViewShell->ExecuteRetypePassDlg(PASSHASH_SHA1))
1850 // password re-type cancelled. Don't save the document.
1851 return false;
1852 }
1853
1854 ScRefreshTimerProtector aProt( m_pDocument->GetRefreshTimerControlAddress() );
1855
1856 PrepareSaveGuard aPrepareGuard( *this);
1857
1858 // wait cursor is handled with progress bar
1859 bool bRet = SfxObjectShell::SaveAs( rMedium );
1860 if (bRet)
1861 bRet = SaveXML( &rMedium, nullptr );
1862
1863 return bRet;
1864}
1865
1866namespace {
1867
1868// Xcl-like column width measured in characters of standard font.
1869sal_Int32 lcl_ScDocShell_GetColWidthInChars( sal_uInt16 nWidth )
1870{
1871 double f = nWidth;
1872 f *= 1328.0 / 25.0;
1873 f += 90.0;
1874 f *= 1.0 / 23.0;
1875 f /= 256.0;
1876
1877 return sal_Int32( f );
1878}
1879
1880void lcl_ScDocShell_GetFixedWidthString( OUString& rStr, const ScDocument& rDoc,
1881 SCTAB nTab, SCCOL nCol, bool bValue, SvxCellHorJustify eHorJust )
1882{
1883 OUString aString = rStr;
1884 sal_Int32 nLen = lcl_ScDocShell_GetColWidthInChars(
1885 rDoc.GetColWidth( nCol, nTab ) );
1886 //If the text won't fit in the column
1887 if ( nLen < aString.getLength() )
1888 {
1889 OUStringBuffer aReplacement;
1890 if (bValue)
1891 aReplacement.append("###");
1892 else
1893 aReplacement.append(aString);
1894 //truncate to the number of characters that should fit, even in the
1895 //bValue case nLen might be < len ###
1896 aString = comphelper::string::truncateToLength(aReplacement, nLen).makeStringAndClear();
1897 }
1898 if ( nLen > aString.getLength() )
1899 {
1900 if ( bValue && eHorJust == SvxCellHorJustify::Standard )
1901 eHorJust = SvxCellHorJustify::Right;
1902 OUStringBuffer aTmp(nLen);
1903 switch ( eHorJust )
1904 {
1905 case SvxCellHorJustify::Right:
1906 comphelper::string::padToLength( aTmp, nLen - aString.getLength(), ' ' );
1907 aString = aTmp.append(aString);
1908 break;
1909 case SvxCellHorJustify::Center:
1910 comphelper::string::padToLength( aTmp, (nLen - aString.getLength()) / 2, ' ' );
1911 [[fallthrough]];
1912 default:
1913 aTmp.append(aString);
1914 comphelper::string::padToLength( aTmp, nLen, ' ' );
1915 }
1916 aString = aTmp.makeStringAndClear();
1917 }
1918 rStr = aString;
1919}
1920
1921void lcl_ScDocShell_WriteEmptyFixedWidthString( SvStream& rStream,
1922 const ScDocument& rDoc, SCTAB nTab, SCCOL nCol )
1923{
1924 OUString aString;
1925 lcl_ScDocShell_GetFixedWidthString( aString, rDoc, nTab, nCol, false,
1926 SvxCellHorJustify::Standard );
1927 rStream.WriteUnicodeOrByteText( aString );
1928}
1929
1930template<typename StrT, typename SepCharT>
1931sal_Int32 getTextSepPos(
1932 const StrT& rStr, const ScImportOptions& rAsciiOpt, const SepCharT& rTextSep, const SepCharT& rFieldSep, bool& rNeedQuotes)
1933{
1934 // #i116636# quotes are needed if text delimiter (quote), field delimiter,
1935 // or LF or CR is in the cell text.
1936 sal_Int32 nPos = rStr.indexOf(rTextSep);
1937 rNeedQuotes = rAsciiOpt.bQuoteAllText || (nPos >= 0) ||
1938 (rStr.indexOf(rFieldSep) >= 0) ||
1939 (rStr.indexOf('\n') >= 0) ||
1940 (rStr.indexOf('\r') >= 0);
1941 return nPos;
1942}
1943
1944}
1945
1946void ScDocShell::AsciiSave( SvStream& rStream, const ScImportOptions& rAsciiOpt, SCTAB nTab )
1947{
1948 sal_Unicode cDelim = rAsciiOpt.nFieldSepCode;
1949 sal_Unicode cStrDelim = rAsciiOpt.nTextSepCode;
1950 rtl_TextEncoding eCharSet = rAsciiOpt.eCharSet;
1951 bool bFixedWidth = rAsciiOpt.bFixedWidth;
1952 bool bSaveNumberAsSuch = rAsciiOpt.bSaveNumberAsSuch;
1953 bool bSaveAsShown = rAsciiOpt.bSaveAsShown;
1954 bool bShowFormulas = rAsciiOpt.bSaveFormulas;
1955 bool bIncludeBOM = rAsciiOpt.bIncludeBOM;
1956
1957 rtl_TextEncoding eOldCharSet = rStream.GetStreamCharSet();
1958 rStream.SetStreamCharSet( eCharSet );
1959 SvStreamEndian nOldNumberFormatInt = rStream.GetEndian();
1960 OString aStrDelimEncoded; // only used if not Unicode
1961 OUString aStrDelimDecoded; // only used if context encoding
1962 OString aDelimEncoded;
1963 OUString aDelimDecoded;
1964 bool bContextOrNotAsciiEncoding;
1965 if ( eCharSet == RTL_TEXTENCODING_UNICODE )
1966 {
1967 rStream.StartWritingUnicodeText();
1968 bContextOrNotAsciiEncoding = false;
1969 }
1970 else
1971 {
1972 // tdf#82254 - check whether to include a byte-order-mark in the output
1973 if (bIncludeBOM && eCharSet == RTL_TEXTENCODING_UTF8)
1974 rStream.WriteUChar(0xEF).WriteUChar(0xBB).WriteUChar(0xBF);
1975 aStrDelimEncoded = OString(&cStrDelim, 1, eCharSet);
1976 aDelimEncoded = OString(&cDelim, 1, eCharSet);
1977 rtl_TextEncodingInfo aInfo;
1978 aInfo.StructSize = sizeof(aInfo);
1979 if ( rtl_getTextEncodingInfo( eCharSet, &aInfo ) )
1980 {
1981 bContextOrNotAsciiEncoding =
1982 (((aInfo.Flags & RTL_TEXTENCODING_INFO_CONTEXT) != 0) ||
1983 ((aInfo.Flags & RTL_TEXTENCODING_INFO_ASCII) == 0));
1984 if ( bContextOrNotAsciiEncoding )
1985 {
1986 aStrDelimDecoded = OStringToOUString(aStrDelimEncoded, eCharSet);
1987 aDelimDecoded = OStringToOUString(aDelimEncoded, eCharSet);
1988 }
1989 }
1990 else
1991 bContextOrNotAsciiEncoding = false;
1992 }
1993
1994 SCCOL nStartCol = 0;
1995 SCROW nStartRow = 0;
1996 SCCOL nEndCol;
1997 SCROW nEndRow;
1998 m_pDocument->GetCellArea( nTab, nEndCol, nEndRow );
1999
2000 ScProgress aProgress( this, ScResId( STR_SAVE_DOC ), nEndRow, true );
2001
2002 OUString aString;
2003
2004 bool bTabProtect = m_pDocument->IsTabProtected( nTab );
2005
2006 SCCOL nCol;
2007 SCROW nRow;
2008
2009 // Treat the top left cell separator "sep=" special.
2010 // Here nStartRow == 0 && nStartCol == 0
2011 if (!bFixedWidth && cDelim != 0)
2012 {
2013 // First row iterator.
2014 ScHorizontalCellIterator aIter( *m_pDocument, nTab, nStartCol, nStartRow, nEndCol, nStartRow);
2015 ScRefCellValue* pCell;
2016 // Must be first column and all following cells on this row must be
2017 // empty to fiddle with "sep=".
2018 if ((pCell = aIter.GetNext( nCol, nRow)) != nullptr && nCol == nStartCol && !aIter.GetNext( nCol, nRow))
2019 {
2020 if (pCell->getType() == CELLTYPE_STRING)
2021 {
2022 aString = pCell->getSharedString()->getString();
2023 if (aString.getLength() <= 5 && aString.startsWithIgnoreAsciiCase("sep="))
2024 {
2025 // Cell content is /^sep=.?$/ so write current separator.
2026 // Force the quote character to '"' regardless what is set
2027 // for export because that is the only one recognized on
2028 // import.
2029 aString = "sep=" + OUStringChar(cDelim);
2030 if (cStrDelim != 0)
2031 rStream.WriteUniOrByteChar( '"', eCharSet);
2032 if (eCharSet == RTL_TEXTENCODING_UNICODE)
2033 {
2034 write_uInt16s_FromOUString( rStream, aString);
2035 }
2036 else
2037 {
2038 OString aStrEnc = OUStringToOString( aString, eCharSet);
2039 // write byte encoded
2040 rStream.WriteBytes( aStrEnc.getStr(), aStrEnc.getLength());
2041 }
2042 if (cStrDelim != 0)
2043 rStream.WriteUniOrByteChar( '"', eCharSet);
2044 endlub( rStream );
2045 ++nStartRow;
2046 }
2047 }
2048 }
2049 }
2050
2051 SCCOL nNextCol = nStartCol;
2052 SCROW nNextRow = nStartRow;
2053 SCCOL nEmptyCol;
2054 SCROW nEmptyRow;
2055 SvNumberFormatter& rFormatter = *m_pDocument->GetFormatTable();
2056
2057 ScHorizontalCellIterator aIter( *m_pDocument, nTab, nStartCol, nStartRow,
2058 nEndCol, nEndRow );
2059 ScRefCellValue* pCell;
2060 while ( ( pCell = aIter.GetNext( nCol, nRow ) ) != nullptr )
2061 {
2062 bool bProgress = false; // only upon line change
2063 if ( nNextRow < nRow )
2064 { // empty rows or/and empty columns up to end of row
2065 bProgress = true;
2066 for ( nEmptyCol = nNextCol; nEmptyCol < nEndCol; nEmptyCol++ )
2067 { // remaining columns of last row
2068 if ( bFixedWidth )
2069 lcl_ScDocShell_WriteEmptyFixedWidthString( rStream,
2070 *m_pDocument, nTab, nEmptyCol );
2071 else if ( cDelim != 0 )
2072 rStream.WriteUniOrByteChar( cDelim );
2073 }
2074 endlub( rStream );
2075 nNextRow++;
2076 for ( nEmptyRow = nNextRow; nEmptyRow < nRow; nEmptyRow++ )
2077 { // completely empty rows
2078 for ( nEmptyCol = nStartCol; nEmptyCol < nEndCol; nEmptyCol++ )
2079 {
2080 if ( bFixedWidth )
2081 lcl_ScDocShell_WriteEmptyFixedWidthString( rStream,
2082 *m_pDocument, nTab, nEmptyCol );
2083 else if ( cDelim != 0 )
2084 rStream.WriteUniOrByteChar( cDelim );
2085 }
2086 endlub( rStream );
2087 }
2088 for ( nEmptyCol = nStartCol; nEmptyCol < nCol; nEmptyCol++ )
2089 { // empty columns at beginning of row
2090 if ( bFixedWidth )
2091 lcl_ScDocShell_WriteEmptyFixedWidthString( rStream,
2092 *m_pDocument, nTab, nEmptyCol );
2093 else if ( cDelim != 0 )
2094 rStream.WriteUniOrByteChar( cDelim );
2095 }
2096 nNextRow = nRow;
2097 }
2098 else if ( nNextCol < nCol )
2099 { // empty columns in same row
2100 for ( nEmptyCol = nNextCol; nEmptyCol < nCol; nEmptyCol++ )
2101 { // columns in between
2102 if ( bFixedWidth )
2103 lcl_ScDocShell_WriteEmptyFixedWidthString( rStream,
2104 *m_pDocument, nTab, nEmptyCol );
2105 else if ( cDelim != 0 )
2106 rStream.WriteUniOrByteChar( cDelim );
2107 }
2108 }
2109 if ( nCol == nEndCol )
2110 {
2111 bProgress = true;
2112 nNextCol = nStartCol;
2113 nNextRow = nRow + 1;
2114 }
2115 else
2116 nNextCol = nCol + 1;
2117
2118 CellType eType = pCell->getType();
2119 ScAddress aPos(nCol, nRow, nTab);
2120 if ( bTabProtect )
2121 {
2122 const ScProtectionAttr* pProtAttr =
2123 m_pDocument->GetAttr( nCol, nRow, nTab, ATTR_PROTECTION );
2124 if ( pProtAttr->GetHideCell() ||
2125 ( eType == CELLTYPE_FORMULA && bShowFormulas &&
2126 pProtAttr->GetHideFormula() ) )
2127 eType = CELLTYPE_NONE; // hide
2128 }
2129 bool bForceQuotes = false;
2130 bool bString;
2131 switch ( eType )
2132 {
2133 case CELLTYPE_NONE:
2134 aString.clear();
2135 bString = false;
2136 break;
2137 case CELLTYPE_FORMULA :
2138 {
2139 FormulaError nErrCode;
2140 if ( bShowFormulas )
2141 {
2142 aString = pCell->getFormula()->GetFormula();
2143 bString = true;
2144 }
2145 else if ((nErrCode = pCell->getFormula()->GetErrCode()) != FormulaError::NONE)
2146 {
2147 aString = ScGlobal::GetErrorString( nErrCode );
2148 bString = true;
2149 }
2150 else if (pCell->getFormula()->IsValue())
2151 {
2152 sal_uInt32 nFormat = m_pDocument->GetNumberFormat(aPos);
2153 if ( bFixedWidth || bSaveAsShown )
2154 {
2155 const Color* pDummy;
2156 aString = ScCellFormat::GetString(*pCell, nFormat, &pDummy, rFormatter, *m_pDocument);
2157 bString = bSaveAsShown && rFormatter.IsTextFormat( nFormat);
2158 }
2159 else
2160 {
2161 aString = ScCellFormat::GetInputString(*pCell, nFormat, rFormatter, *m_pDocument);
2162 bString = bForceQuotes = !bSaveNumberAsSuch;
2163 }
2164 }
2165 else
2166 {
2167 if ( bSaveAsShown )
2168 {
2169 sal_uInt32 nFormat = m_pDocument->GetNumberFormat(aPos);
2170 const Color* pDummy;
2171 aString = ScCellFormat::GetString(*pCell, nFormat, &pDummy, rFormatter, *m_pDocument);
2172 }
2173 else
2174 aString = pCell->getFormula()->GetString().getString();
2175 bString = true;
2176 }
2177 }
2178 break;
2179 case CELLTYPE_STRING :
2180 if ( bSaveAsShown )
2181 {
2182 sal_uInt32 nFormat = m_pDocument->GetNumberFormat(aPos);
2183 const Color* pDummy;
2184 aString = ScCellFormat::GetString(*pCell, nFormat, &pDummy, rFormatter, *m_pDocument);
2185 }
2186 else
2187 aString = pCell->getSharedString()->getString();
2188 bString = true;
2189 break;
2190 case CELLTYPE_EDIT :
2191 {
2192 const EditTextObject* pObj = pCell->getEditText();
2193 EditEngine& rEngine = m_pDocument->GetEditEngine();
2194 rEngine.SetText( *pObj);
2195 aString = rEngine.GetText(); // including LF
2196 bString = true;
2197 }
2198 break;
2199 case CELLTYPE_VALUE :
2200 {
2201 sal_uInt32 nFormat = m_pDocument->GetNumberFormat( nCol, nRow, nTab );
2202 if ( bFixedWidth || bSaveAsShown )
2203 {
2204 const Color* pDummy;
2205 aString = ScCellFormat::GetString(*pCell, nFormat, &pDummy, rFormatter, *m_pDocument);
2206 bString = bSaveAsShown && rFormatter.IsTextFormat( nFormat);
2207 }
2208 else
2209 {
2210 aString = ScCellFormat::GetInputString(*pCell, nFormat, rFormatter, *m_pDocument);
2211 bString = bForceQuotes = !bSaveNumberAsSuch;
2212 }
2213 }
2214 break;
2215 default:
2216 OSL_FAIL( "ScDocShell::AsciiSave: unknown CellType" );
2217 aString.clear();
2218 bString = false;
2219 }
2220
2221 if ( bFixedWidth )
2222 {
2223 SvxCellHorJustify eHorJust =
2224 m_pDocument->GetAttr( nCol, nRow, nTab, ATTR_HOR_JUSTIFY )->GetValue();
2225 lcl_ScDocShell_GetFixedWidthString( aString, *m_pDocument, nTab, nCol,
2226 !bString, eHorJust );
2227 rStream.WriteUnicodeOrByteText( aString );
2228 }
2229 else
2230 {
2231 OUString aUniString = aString;// TODO: remove that later
2232 if (!bString && cStrDelim != 0 && !aUniString.isEmpty())
2233 {
2234 sal_Unicode c = aUniString[0];
2235 bString = (c == cStrDelim || c == ' ' ||
2236 aUniString.endsWith(" ") ||
2237 aUniString.indexOf(cStrDelim) >= 0);
2238 if (!bString && cDelim != 0)
2239 bString = (aUniString.indexOf(cDelim) >= 0);
2240 }
2241 if ( bString )
2242 {
2243 if ( cStrDelim != 0 ) //@ BugId 55355
2244 {
2245 if ( eCharSet == RTL_TEXTENCODING_UNICODE )
2246 {
2247 bool bNeedQuotes = false;
2248 sal_Int32 nPos = getTextSepPos(aUniString, rAsciiOpt, cStrDelim, cDelim, bNeedQuotes);
2249 if (nPos >= 0)
2250 {
2251 OUString strFrom(cStrDelim);
2252 OUString strTo = strFrom + strFrom;
2253 aUniString = aUniString.replaceAll(strFrom, strTo);
2254 }
2255
2256 if ( bNeedQuotes || bForceQuotes )
2257 rStream.WriteUniOrByteChar( cStrDelim, eCharSet );
2258 write_uInt16s_FromOUString(rStream, aUniString);
2259 if ( bNeedQuotes || bForceQuotes )
2260 rStream.WriteUniOrByteChar( cStrDelim, eCharSet );
2261 }
2262 else
2263 {
2264 // This is nasty. The Unicode to byte encoding
2265 // may convert typographical quotation marks to ASCII
2266 // quotation marks, which may interfere with the delimiter,
2267 // so we have to escape delimiters after the string has
2268 // been encoded. Since this may happen also with UTF-8
2269 // encoded typographical quotation marks if such was
2270 // specified as a delimiter we have to check for the full
2271 // encoded delimiter string, not just one character.
2272 // Now for RTL_TEXTENCODING_ISO_2022_... and similar brain
2273 // dead encodings where one code point (and especially a
2274 // low ASCII value) may represent different characters, we
2275 // have to convert forth and back and forth again. Same for
2276 // UTF-7 since it is a context sensitive encoding too.
2277
2278 if ( bContextOrNotAsciiEncoding )
2279 {
2280 // to byte encoding
2281 OString aStrEnc = OUStringToOString(aUniString, eCharSet);
2282 // back to Unicode
2283 OUString aStrDec = OStringToOUString(aStrEnc, eCharSet);
2284
2285 // search on re-decoded string
2286 bool bNeedQuotes = false;
2287 sal_Int32 nPos = getTextSepPos(aStrDec, rAsciiOpt, aStrDelimDecoded, aDelimDecoded, bNeedQuotes);
2288 if (nPos >= 0)
2289 {
2290 OUString strTo = aStrDelimDecoded + aStrDelimDecoded;
2291 aStrDec = aStrDec.replaceAll(aStrDelimDecoded, strTo);
2292 }
2293
2294 // write byte re-encoded
2295 if ( bNeedQuotes || bForceQuotes )
2296 rStream.WriteUniOrByteChar( cStrDelim, eCharSet );
2297 rStream.WriteUnicodeOrByteText( aStrDec, eCharSet );
2298 if ( bNeedQuotes || bForceQuotes )
2299 rStream.WriteUniOrByteChar( cStrDelim, eCharSet );
2300 }
2301 else
2302 {
2303 OString aStrEnc = OUStringToOString(aUniString, eCharSet);
2304
2305 // search on encoded string
2306 bool bNeedQuotes = false;
2307 sal_Int32 nPos = getTextSepPos(aStrEnc, rAsciiOpt, aStrDelimEncoded, aDelimEncoded, bNeedQuotes);
2308 if (nPos >= 0)
2309 {
2310 OString strTo = aStrDelimEncoded + aStrDelimEncoded;
2311 aStrEnc = aStrEnc.replaceAll(aStrDelimEncoded, strTo);
2312 }
2313
2314 // write byte encoded
2315 if ( bNeedQuotes || bForceQuotes )
2316 rStream.WriteBytes(
2317 aStrDelimEncoded.getStr(), aStrDelimEncoded.getLength());
2318 rStream.WriteBytes(aStrEnc.getStr(), aStrEnc.getLength());
2319 if ( bNeedQuotes || bForceQuotes )
2320 rStream.WriteBytes(
2321 aStrDelimEncoded.getStr(), aStrDelimEncoded.getLength());
2322 }
2323 }
2324 }
2325 else
2326 rStream.WriteUnicodeOrByteText( aUniString );
2327 }
2328 else
2329 rStream.WriteUnicodeOrByteText( aUniString );
2330 }
2331
2332 if( nCol < nEndCol )
2333 {
2334 if(cDelim!=0) //@ BugId 55355
2335 rStream.WriteUniOrByteChar( cDelim );
2336 }
2337 else
2338 endlub( rStream );
2339
2340 if ( bProgress )
2341 aProgress.SetStateOnPercent( nRow );
2342 }
2343
2344 // write out empty if requested
2345 if ( nNextRow <= nEndRow )
2346 {
2347 for ( nEmptyCol = nNextCol; nEmptyCol < nEndCol; nEmptyCol++ )
2348 { // remaining empty columns of last row
2349 if ( bFixedWidth )
2350 lcl_ScDocShell_WriteEmptyFixedWidthString( rStream,
2351 *m_pDocument, nTab, nEmptyCol );
2352 else if ( cDelim != 0 )
2353 rStream.WriteUniOrByteChar( cDelim );
2354 }
2355 endlub( rStream );
2356 nNextRow++;
2357 }
2358 for ( nEmptyRow = nNextRow; nEmptyRow <= nEndRow; nEmptyRow++ )
2359 { // entire empty rows
2360 for ( nEmptyCol = nStartCol; nEmptyCol < nEndCol; nEmptyCol++ )
2361 {
2362 if ( bFixedWidth )
2363 lcl_ScDocShell_WriteEmptyFixedWidthString( rStream,
2364 *m_pDocument, nTab, nEmptyCol );
2365 else if ( cDelim != 0 )
2366 rStream.WriteUniOrByteChar( cDelim );
2367 }
2368 endlub( rStream );
2369 }
2370
2371 rStream.SetStreamCharSet( eOldCharSet );
2372 rStream.SetEndian( nOldNumberFormatInt );
2373}
2374
2376{
2377 ScRefreshTimerProtector aProt( m_pDocument->GetRefreshTimerControlAddress() );
2378
2379 // #i6500# don't call DoEnterHandler here (doesn't work with AutoSave),
2380 // it's already in ExecuteSave (as for Save and SaveAs)
2381
2382 if (m_pAutoStyleList)
2383 m_pAutoStyleList->ExecuteAllNow(); // Execute template timeouts now
2384 if (GetCreateMode()== SfxObjectCreateMode::STANDARD)
2385 SfxObjectShell::SetVisArea( tools::Rectangle() ); // Edited normally -> no VisArea
2386
2387 OSL_ENSURE( rMed.GetFilter(), "Filter == 0" );
2388
2389 bool bRet = false;
2390 OUString aFltName = rMed.GetFilter()->GetFilterName();
2391
2392 if (aFltName == pFilterXML)
2393 {
2394 //TODO/LATER: this shouldn't happen!
2395 OSL_FAIL("XML filter in ConvertFrom?!");
2396 bRet = SaveXML( &rMed, nullptr );
2397 }
2398 else if (aFltName == pFilterExcel5 || aFltName == pFilterExcel95 ||
2399 aFltName == pFilterExcel97 || aFltName == pFilterEx5Temp ||
2400 aFltName == pFilterEx95Temp || aFltName == pFilterEx97Temp)
2401 {
2403
2404 bool bDoSave = true;
2405 if( ScTabViewShell* pViewShell = GetBestViewShell() )
2406 {
2407 ScExtDocOptions* pExtDocOpt = m_pDocument->GetExtDocOptions();
2408 if( !pExtDocOpt )
2409 {
2410 m_pDocument->SetExtDocOptions( std::make_unique<ScExtDocOptions>() );
2411 pExtDocOpt = m_pDocument->GetExtDocOptions();
2412 }
2413 pViewShell->GetViewData().WriteExtOptions( *pExtDocOpt );
2414
2415 /* #i104990# If the imported document contains a medium
2416 password, determine if we can save it, otherwise ask the users
2417 whether they want to save without it. */
2418 if( (rMed.GetFilter()->GetFilterFlags() & SfxFilterFlags::ENCRYPTION) == SfxFilterFlags::NONE )
2419 {
2420 SfxItemSet* pItemSet = rMed.GetItemSet();
2421 if( pItemSet && pItemSet->GetItemState( SID_PASSWORD ) == SfxItemState::SET )
2422 {
2423 bDoSave = ScWarnPassword::WarningOnPassword( rMed );
2424 // #i42858# remove password from medium (warn only one time)
2425 if( bDoSave )
2426 pItemSet->ClearItem( SID_PASSWORD );
2427 }
2428 }
2429
2430 if( bDoSave )
2431 {
2432 bool bNeedRetypePassDlg = ScPassHashHelper::needsPassHashRegen( *m_pDocument, PASSHASH_XL );
2433 bDoSave = !bNeedRetypePassDlg || pViewShell->ExecuteRetypePassDlg( PASSHASH_XL );
2434 }
2435 }
2436
2437 if( bDoSave )
2438 {
2439 ExportFormatExcel eFormat = ExpBiff5;
2440 if( aFltName == pFilterExcel97 || aFltName == pFilterEx97Temp )
2441 eFormat = ExpBiff8;
2442 ErrCode eError = ScFormatFilter::Get().ScExportExcel5( rMed, m_pDocument.get(), eFormat, RTL_TEXTENCODING_MS_1252 );
2443
2444 if( eError && !GetError() )
2445 SetError(eError);
2446
2447 // don't return false for warnings
2448 bRet = eError.IsWarning() || (eError == ERRCODE_NONE);
2449 }
2450 else
2451 {
2452 // export aborted, i.e. "Save without password" warning
2454 }
2455 }
2456 else if (aFltName == SC_TEXT_CSV_FILTER_NAME)
2457 {
2458 OUString sItStr;
2459 SfxItemSet* pSet = rMed.GetItemSet();
2460 const SfxStringItem* pOptionsItem;
2461 if ( pSet &&
2462 (pOptionsItem = pSet->GetItemIfSet( SID_FILE_FILTEROPTIONS )) )
2463 {
2464 sItStr = pOptionsItem->GetValue();
2465 }
2466
2467 if ( sItStr.isEmpty() )
2468 {
2469 // default for ascii export (from API without options):
2470 // UTF-8 encoding, comma, double quotes
2471
2472 ScImportOptions aDefOptions(',', '"', RTL_TEXTENCODING_UTF8);
2473 sItStr = aDefOptions.BuildString();
2474 }
2475
2477 ScImportOptions aOptions( sItStr );
2478
2479 if (aOptions.nSheetToExport)
2480 {
2481 // Only from command line --convert-to
2482 bRet = true;
2483
2484 // Verbose only from command line, not UI (in case we actually
2485 // implement that) nor macro filter options.
2486 bool bVerbose = false;
2487 const css::uno::Sequence<css::beans::PropertyValue> & rArgs = rMed.GetArgs();
2488 const auto pProp = std::find_if( rArgs.begin(), rArgs.end(),
2489 [](const css::beans::PropertyValue& rProp) { return rProp.Name == "ConversionRequestOrigin"; });
2490 if (pProp != rArgs.end())
2491 {
2492 OUString aOrigin;
2493 pProp->Value >>= aOrigin;
2494 bVerbose = (aOrigin == "CommandLine");
2495 }
2496
2497 SCTAB nStartTab;
2498 SCTAB nCount = m_pDocument->GetTableCount();
2499 if (aOptions.nSheetToExport == -1)
2500 {
2501 // All sheets.
2502 nStartTab = 0;
2503 }
2504 else if (0 < aOptions.nSheetToExport && aOptions.nSheetToExport <= nCount)
2505 {
2506 // One sheet, 1-based.
2507 nCount = aOptions.nSheetToExport;
2508 nStartTab = nCount - 1;
2509 }
2510 else
2511 {
2512 // Usage error, no export but log.
2513 if (bVerbose)
2514 {
2515 if (aOptions.nSheetToExport < 0)
2516 std::cout << "Bad sheet number string given." << std::endl;
2517 else
2518 std::cout << "No sheet number " << aOptions.nSheetToExport
2519 << ", number of sheets is " << nCount << std::endl;
2520 }
2521 nStartTab = 0;
2522 nCount = 0;
2524 bRet = false;
2525 }
2526
2527 INetURLObject aURLObject(rMed.GetURLObject());
2528 OUString sExt = aURLObject.CutExtension();
2529 OUString sBaseName = aURLObject.GetLastName();
2530 aURLObject.CutLastName();
2531
2532 for (SCTAB i = nStartTab; i < nCount; ++i)
2533 {
2534 OUString sTabName;
2535 if (!m_pDocument->GetName(i, sTabName))
2536 sTabName = OUString::number(i);
2537 INetURLObject aSheetURLObject(aURLObject);
2538 OUString sFileName = sBaseName + "-" + sTabName;
2539 if (!sExt.isEmpty())
2540 sFileName = sFileName + "." + sExt;
2541 aSheetURLObject.Append(sFileName);
2542
2543 // log similar to DispatchWatcher::executeDispatchRequests
2544 OUString aOutFile = aSheetURLObject.GetMainURL(INetURLObject::DecodeMechanism::NONE);
2545 if (bVerbose)
2546 {
2547 OUString aDisplayedName;
2548 if (osl::FileBase::E_None != osl::FileBase::getSystemPathFromFileURL(aOutFile, aDisplayedName))
2549 aDisplayedName = aOutFile;
2550 std::cout << "Writing sheet " << OUStringToOString(sTabName, osl_getThreadTextEncoding()) << " -> "
2551 << OUStringToOString(aDisplayedName, osl_getThreadTextEncoding())
2552 << std::endl;
2553
2554 if (FStatHelper::IsDocument(aOutFile))
2555 std::cout << "Overwriting: " << OUStringToOString(aDisplayedName, osl_getThreadTextEncoding())
2556 << std::endl ;
2557 }
2558
2559 std::unique_ptr<SvStream> xStm = ::utl::UcbStreamHelper::CreateStream(aOutFile, StreamMode::TRUNC | StreamMode::WRITE);
2560 if (!xStm)
2561 {
2563 bRet = false;
2564 break;
2565 }
2566 AsciiSave(*xStm, aOptions, i);
2567 }
2568 }
2569 else
2570 {
2571 SvStream* pStream = rMed.GetOutStream();
2572 if (pStream)
2573 {
2574 AsciiSave(*pStream, aOptions, GetSaveTab());
2575 bRet = true;
2576
2577 if (m_pDocument->GetTableCount() > 1)
2578 if (!rMed.GetError())
2580 }
2581 }
2582 }
2583 else if (aFltName == pFilterDBase)
2584 {
2585 OUString sCharSet;
2586 SfxItemSet* pSet = rMed.GetItemSet();
2587 const SfxStringItem* pOptionsItem;
2588 if ( pSet &&
2589 (pOptionsItem = pSet->GetItemIfSet( SID_FILE_FILTEROPTIONS )) )
2590 {
2591 sCharSet = pOptionsItem->GetValue();
2592 }
2593
2594 if (sCharSet.isEmpty())
2595 {
2596 // default for dBase export (from API without options):
2597 // IBM_850 encoding
2598
2599 sCharSet = ScGlobal::GetCharsetString( RTL_TEXTENCODING_IBM_850 );
2600 }
2601
2603 // Hack so that Sba can overwrite the opened TempFile.
2604 rMed.CloseOutStream();
2605 bool bHasMemo = false;
2606
2607 ErrCode eError = DBaseExport(
2608 rMed.GetPhysicalName(), ScGlobal::GetCharsetValue(sCharSet), bHasMemo);
2609
2610 INetURLObject aTmpFile( rMed.GetPhysicalName(), INetProtocol::File );
2611 if ( bHasMemo )
2612 aTmpFile.setExtension(u"dbt");
2613 if ( eError != ERRCODE_NONE && !eError.IsWarning() )
2614 {
2615 if (!GetError())
2616 SetError(eError);
2617 if ( bHasMemo && IsDocument( aTmpFile ) )
2618 KillFile( aTmpFile );
2619 }
2620 else
2621 {
2622 bRet = true;
2623 if ( bHasMemo )
2624 {
2625 const SfxStringItem* pNameItem = rMed.GetItemSet()->GetItem<SfxStringItem>( SID_FILE_NAME );
2626 assert(pNameItem && "SID_FILE_NAME is required");
2627 INetURLObject aDbtFile( pNameItem->GetValue(), INetProtocol::File );
2628 aDbtFile.setExtension(u"dbt");
2629
2630 // tdf#40713: don't lose dbt file
2631 // if aDbtFile corresponds exactly to aTmpFile, we just have to return
2634 {
2635 if (eError != ERRCODE_NONE && !GetError())
2636 SetError(eError);
2637 return bRet;
2638 }
2639
2640 if ( IsDocument( aDbtFile ) && !KillFile( aDbtFile ) )
2641 bRet = false;
2642 if ( bRet && !MoveFile( aTmpFile, aDbtFile ) )
2643 bRet = false;
2644 if ( !bRet )
2645 {
2646 KillFile( aTmpFile );
2647 if (eError == ERRCODE_NONE || eError.IsWarning())
2648 eError = SCERR_EXPORT_DATA;
2649 }
2650 }
2651 if (eError != ERRCODE_NONE && !GetError())
2652 SetError(eError);
2653 }
2654 }
2655 else if (aFltName == pFilterDif)
2656 {
2657 SvStream* pStream = rMed.GetOutStream();
2658 if (pStream)
2659 {
2660 OUString sItStr;
2661 SfxItemSet* pSet = rMed.GetItemSet();
2662 const SfxStringItem* pOptionsItem;
2663 if ( pSet &&
2664 (pOptionsItem = pSet->GetItemIfSet( SID_FILE_FILTEROPTIONS )) )
2665 {
2666 sItStr = pOptionsItem->GetValue();
2667 }
2668
2669 if (sItStr.isEmpty())
2670 {
2671 // default for DIF export (from API without options):
2672 // ISO8859-1/MS_1252 encoding
2673
2674 sItStr = ScGlobal::GetCharsetString( RTL_TEXTENCODING_MS_1252 );
2675 }
2676
2678 ScFormatFilter::Get().ScExportDif( *pStream, m_pDocument.get(), ScAddress(0,0,0),
2679 ScGlobal::GetCharsetValue(sItStr) );
2680 bRet = true;
2681
2682 if (m_pDocument->GetTableCount() > 1)
2683 if (!rMed.GetError())
2685 }
2686 }
2687 else if (aFltName == pFilterSylk)
2688 {
2689 SvStream* pStream = rMed.GetOutStream();
2690 if ( pStream )
2691 {
2693
2694 SCCOL nEndCol;
2695 SCROW nEndRow;
2696 m_pDocument->GetCellArea( 0, nEndCol, nEndRow );
2697 ScRange aRange( 0,0,0, nEndCol,nEndRow,0 );
2698
2699 ScImportExport aImExport( *m_pDocument, aRange );
2700 aImExport.SetFormulas( true );
2701 bRet = aImExport.ExportStream( *pStream, rMed.GetBaseURL( true ), SotClipboardFormatId::SYLK );
2702 }
2703 }
2704 else if (aFltName == pFilterHtml)
2705 {
2706 SvStream* pStream = rMed.GetOutStream();
2707 if ( pStream )
2708 {
2709 SfxItemSet* pSet = rMed.GetItemSet();
2710 OUString sFilterOptions;
2711
2712 if (const SfxStringItem* pOptionsItem = pSet->GetItemIfSet(SID_FILE_FILTEROPTIONS))
2713 sFilterOptions = pOptionsItem->GetValue();
2714
2716 ScImportExport aImExport(*m_pDocument);
2717 aImExport.SetStreamPath(rMed.GetName());
2718 aImExport.SetFilterOptions(sFilterOptions);
2719 bRet = aImExport.ExportStream(*pStream, rMed.GetBaseURL(true), SotClipboardFormatId::HTML);
2720 if (bRet && !aImExport.GetNonConvertibleChars().isEmpty())
2721 {
2724 aImExport.GetNonConvertibleChars(),
2725 DialogMask::ButtonsOk | DialogMask::MessageInfo));
2726 }
2727 }
2728 }
2729 else
2730 {
2731 if (GetError())
2733 }
2734 return bRet;
2735}
2736
2737bool ScDocShell::DoSaveCompleted( SfxMedium * pNewStor, bool bRegisterRecent )
2738{
2739 bool bRet = SfxObjectShell::DoSaveCompleted( pNewStor, bRegisterRecent );
2740
2741 // SfxHintId::ScDocSaved for change ReadOnly -> Read/Write
2742 Broadcast( SfxHint( SfxHintId::ScDocSaved ) );
2743 return bRet;
2744}
2745
2746bool ScDocShell::QuerySlotExecutable( sal_uInt16 nSlotId )
2747{
2748 // #i112634# ask VBA event handlers whether to save or print the document
2749
2750 using namespace ::com::sun::star::script::vba;
2751
2752 sal_Int32 nVbaEventId = VBAEventId::NO_EVENT;
2753 uno::Sequence< uno::Any > aArgs;
2754 switch( nSlotId )
2755 {
2756 case SID_SAVEDOC:
2757 case SID_SAVEASDOC:
2758 nVbaEventId = VBAEventId::WORKBOOK_BEFORESAVE;
2759 aArgs = { uno::Any(nSlotId == SID_SAVEASDOC) };
2760 break;
2761 case SID_PRINTDOC:
2762 case SID_PRINTDOCDIRECT:
2763 nVbaEventId = VBAEventId::WORKBOOK_BEFOREPRINT;
2764 break;
2765 }
2766
2767 bool bSlotExecutable = true;
2768 if( nVbaEventId != VBAEventId::NO_EVENT ) try
2769 {
2770 uno::Reference< XVBAEventProcessor > xEventProcessor( m_pDocument->GetVbaEventProcessor(), uno::UNO_SET_THROW );
2771 xEventProcessor->processVbaEvent( nVbaEventId, aArgs );
2772 }
2773 catch( util::VetoException& )
2774 {
2775 bSlotExecutable = false;
2776 }
2777 catch( uno::Exception& )
2778 {
2779 }
2780 return bSlotExecutable;
2781}
2782
2784{
2785 if(SC_MOD()->GetCurRefDlgId()>0)
2786 {
2787 SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this );
2788 if( pFrame )
2789 {
2790 SfxViewShell* p = pFrame->GetViewShell();
2791 ScTabViewShell* pViewSh = dynamic_cast< ScTabViewShell *>( p );
2792 if(pViewSh!=nullptr)
2793 {
2794 vcl::Window *pWin=pViewSh->GetWindow();
2795 if(pWin!=nullptr) pWin->GrabFocus();
2796 }
2797 }
2798
2799 return false;
2800 }
2801 if ( m_pDocument->IsInLinkUpdate() || m_pDocument->IsInInterpreter() )
2802 {
2803 ErrorMessage(STR_CLOSE_ERROR_LINK);
2804 return false;
2805 }
2806
2808
2809 // start 'Workbook_BeforeClose' VBA event handler for possible veto
2810 if( !IsInPrepareClose() )
2811 {
2812 try
2813 {
2814 uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents( m_pDocument->GetVbaEventProcessor(), uno::UNO_SET_THROW );
2815 uno::Sequence< uno::Any > aArgs;
2816 xVbaEvents->processVbaEvent( script::vba::VBAEventId::WORKBOOK_BEFORECLOSE, aArgs );
2817 }
2818 catch( util::VetoException& )
2819 {
2820 // if event processor throws VetoException, macro has vetoed close
2821 return false;
2822 }
2823 catch( uno::Exception& )
2824 {
2825 }
2826 }
2827 // end handler code
2828
2829 bool bRet = SfxObjectShell::PrepareClose( bUI );
2830 if (bRet) // true == close
2831 m_pDocument->EnableIdle(false); // Do not mess around with it anymore!
2832
2833 return bRet;
2834}
2835
2837{
2838 return pFilterSc50;
2839}
2840
2842{
2843 return pFilterHtml;
2844}
2845
2847{
2848 return pFilterHtmlWebQ;
2849}
2850
2852{
2854}
2855
2857{
2858 return pFilterLotus;
2859}
2860
2862{
2863 return pFilterDBase;
2864}
2865
2867{
2868 return pFilterDif;
2869}
2870
2871bool ScDocShell::HasAutomaticTableName( std::u16string_view rFilter )
2872{
2873 // sal_True for those filters that keep the default table name
2874 // (which is language specific)
2875
2876 return rFilter == SC_TEXT_CSV_FILTER_NAME
2877 || rFilter == pFilterLotus
2878 || rFilter == pFilterExcel4
2879 || rFilter == pFilterEx4Temp
2880 || rFilter == pFilterDBase
2881 || rFilter == pFilterDif
2882 || rFilter == pFilterSylk
2883 || rFilter == pFilterHtml
2884 || rFilter == pFilterRtf;
2885}
2886
2887std::unique_ptr<ScDocFunc> ScDocShell::CreateDocFunc()
2888{
2889 return std::make_unique<ScDocFuncDirect>( *this );
2890}
2891
2892ScDocShell::ScDocShell( const SfxModelFlags i_nSfxCreationFlags, const std::shared_ptr<ScDocument>& pDoc ) :
2893 SfxObjectShell( i_nSfxCreationFlags ),
2894 m_pDocument ( pDoc ? pDoc : std::make_shared<ScDocument>( SCDOCMODE_DOCUMENT, this )),
2895 m_aDdeTextFmt(OUString("TEXT")),
2896 m_nPrtToScreenFactor( 1.0 ),
2897 m_pImpl ( new DocShell_Impl ),
2898 m_bHeaderOn ( true ),
2899 m_bFooterOn ( true ),
2900 m_bIsEmpty ( true ),
2901 m_bIsInUndo ( false ),
2903 m_bUpdateEnabled ( true ),
2905 m_nDocumentLock ( 0 ),
2906 m_nCanUpdate (css::document::UpdateDocMode::ACCORDING_TO_CONFIG)
2907{
2908 SetPool( &SC_MOD()->GetPool() );
2909
2910 m_bIsInplace = (GetCreateMode() == SfxObjectCreateMode::EMBEDDED);
2911 // Will be reset if not in place
2912
2914
2915 // SetBaseModel needs exception handling
2917
2918 StartListening(*this);
2919 SfxStyleSheetPool* pStlPool = m_pDocument->GetStyleSheetPool();
2920 if (pStlPool)
2921 StartListening(*pStlPool);
2922
2923 m_pDocument->GetDBCollection()->SetRefreshHandler(
2924 LINK( this, ScDocShell, RefreshDBDataHdl ) );
2925
2926 // InitItems and CalcOutputFactor are called now in Load/ConvertFrom/InitNew
2927}
2928
2930{
2931 ResetDrawObjectShell(); // If the Drawing Layer still tries to access it, access it
2932
2933 SfxStyleSheetPool* pStlPool = m_pDocument->GetStyleSheetPool();
2934 if (pStlPool)
2935 EndListening(*pStlPool);
2936 EndListening(*this);
2937
2938 m_pAutoStyleList.reset();
2939
2940 SfxApplication *pSfxApp = SfxGetpApp();
2941 if ( pSfxApp->GetDdeService() ) // Delete DDE for Document
2942 pSfxApp->RemoveDdeTopic( this );
2943
2944 m_pDocFunc.reset();
2945 delete m_pDocument->mpUndoManager;
2946 m_pDocument->mpUndoManager = nullptr;
2947 m_pImpl.reset();
2948
2949 m_pPaintLockData.reset();
2950
2951 m_pSolverSaveData.reset();
2952 m_pSheetSaveData.reset();
2953 m_pFormatSaveData.reset();
2954 m_pOldAutoDBRange.reset();
2955
2956 if (m_pModificator)
2957 {
2958 OSL_FAIL("The Modificator should not exist");
2959 m_pModificator.reset();
2960 }
2961}
2962
2964{
2965 return m_pDocument->GetUndoManager();
2966}
2967
2968void ScDocShell::SetModified( bool bModified )
2969{
2971 {
2972 SfxObjectShell::SetModified( bModified );
2973 Broadcast( SfxHint( SfxHintId::DocChanged ) );
2974 }
2975}
2976
2978{
2979 // BroadcastUno must also happen right away with pPaintLockData
2980 // FIXME: Also for SetDrawModified, if Drawing is connected
2981 // FIXME: Then own Hint?
2982
2983 if ( m_pPaintLockData )
2984 {
2985 // #i115009# broadcast BCA_BRDCST_ALWAYS, so a component can read recalculated results
2986 // of RecalcModeAlways formulas (like OFFSET) after modifying cells
2987 m_pDocument->Broadcast(ScHint(SfxHintId::ScDataChanged, BCA_BRDCST_ALWAYS));
2988 m_pDocument->InvalidateTableArea(); // #i105279# needed here
2989 m_pDocument->BroadcastUno( SfxHint( SfxHintId::DataChanged ) );
2990
2991 m_pPaintLockData->SetModified(); // Later on ...
2992 return;
2993 }
2994
2996
2997 if ( m_pDocument->IsAutoCalcShellDisabled() )
2999 else
3000 {
3002 m_pDocument->InvalidateStyleSheetUsage();
3003 m_pDocument->InvalidateTableArea();
3004 m_pDocument->InvalidateLastTableOpParams();
3005 m_pDocument->Broadcast(ScHint(SfxHintId::ScDataChanged, BCA_BRDCST_ALWAYS));
3006 if ( m_pDocument->IsForcedFormulaPending() && m_pDocument->GetAutoCalc() )
3007 m_pDocument->CalcFormulaTree( true );
3008 m_pDocument->RefreshDirtyTableColumnNames();
3010
3011 // Detective AutoUpdate:
3012 // Update if formulas were modified (DetectiveDirty) or the list contains
3013 // "Trace Error" entries (Trace Error can look completely different
3014 // after changes to non-formula cells).
3015
3016 ScDetOpList* pList = m_pDocument->GetDetOpList();
3017 if ( pList && ( m_pDocument->IsDetectiveDirty() || pList->HasAddError() ) &&
3018 pList->Count() && !IsInUndo() && SC_MOD()->GetAppOptions().GetDetectiveAuto() )
3019 {
3020 GetDocFunc().DetectiveRefresh(true); // sal_True = caused by automatic update
3021 }
3022 m_pDocument->SetDetectiveDirty(false); // always reset, also if not refreshed
3023 }
3024
3026 {
3028 SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScAreasChanged));
3029 }
3030
3031 // notify UNO objects after BCA_BRDCST_ALWAYS etc.
3032 m_pDocument->BroadcastUno( SfxHint( SfxHintId::DataChanged ) );
3033}
3034
3042{
3043 bool bUpdate = !IsModified();
3044
3045 SetModified();
3046
3047 SfxBindings* pBindings = GetViewBindings();
3048 if (bUpdate && pBindings)
3049 {
3050 pBindings->Invalidate( SID_SAVEDOC );
3051 pBindings->Invalidate( SID_DOC_MODIFIED );
3052 }
3053
3054 if (pBindings)
3055 {
3056 // #i105960# Undo etc used to be volatile.
3057 // They always have to be invalidated, including drawing layer or row height changes
3058 // (but not while pPaintLockData is set).
3059 pBindings->Invalidate( SID_UNDO );
3060 pBindings->Invalidate( SID_REDO );
3061 pBindings->Invalidate( SID_REPEAT );
3062 }
3063
3064 if ( m_pDocument->IsChartListenerCollectionNeedsUpdate() )
3065 {
3066 m_pDocument->UpdateChartListenerCollection();
3067 SfxGetpApp()->Broadcast(SfxHint( SfxHintId::ScDrawChanged )); // Navigator
3068 }
3069 SC_MOD()->AnythingChanged();
3070}
3071
3073{
3074 m_bIsInUndo = bSet;
3075}
3076
3078{
3079 SfxPrinter* pPrinter = GetPrinter();
3080
3081 m_pDocument->GetDocStat( rDocStat );
3082 rDocStat.nPageCount = 0;
3083
3084 if ( pPrinter )
3085 for ( SCTAB i=0; i<rDocStat.nTableCount; i++ )
3086 rDocStat.nPageCount = sal::static_int_cast<sal_uInt16>( rDocStat.nPageCount +
3087 static_cast<sal_uInt16>(ScPrintFunc( this, pPrinter, i ).GetTotalPages()) );
3088}
3089
3090std::shared_ptr<SfxDocumentInfoDialog> ScDocShell::CreateDocumentInfoDialog(weld::Window* pParent, const SfxItemSet &rSet)
3091{
3092 std::shared_ptr<SfxDocumentInfoDialog> xDlg = std::make_shared<SfxDocumentInfoDialog>(pParent, rSet);
3093 ScDocShell* pDocSh = dynamic_cast< ScDocShell *>( SfxObjectShell::Current() );
3094
3095 // Only for statistics, if this Doc is shown; not from the Doc Manager
3096 if( pDocSh == this )
3097 {
3099 ::CreateTabPage ScDocStatPageCreate = pFact->GetTabPageCreatorFunc(SID_SC_TP_STAT);
3100 OSL_ENSURE(ScDocStatPageCreate, "Tabpage create fail!");
3101 xDlg->AddFontTabPage();
3102 xDlg->AddTabPage("calcstats", ScResId(STR_DOC_STAT), ScDocStatPageCreate);
3103 }
3104 return xDlg;
3105}
3106
3108{
3110 if ( pViewSh )
3111 return pViewSh->GetDialogParent();
3113}
3114
3115void ScDocShell::SetSolverSaveData( std::unique_ptr<ScOptSolverSave> pData )
3116{
3117 m_pSolverSaveData = std::move(pData);
3118}
3119
3121{
3122 if (!m_pSheetSaveData)
3123 m_pSheetSaveData.reset( new ScSheetSaveData );
3124
3125 return m_pSheetSaveData.get();
3126}
3127
3129{
3130 if (!m_pFormatSaveData)
3132
3133 return m_pFormatSaveData.get();
3134}
3135
3136namespace {
3137
3138void removeKeysIfExists(const Reference<ui::XAcceleratorConfiguration>& xScAccel, const vector<const awt::KeyEvent*>& rKeys)
3139{
3140 for (const awt::KeyEvent* p : rKeys)
3141 {
3142 if (!p)
3143 continue;
3144
3145 try
3146 {
3147 xScAccel->removeKeyEvent(*p);
3148 }
3149 catch (const container::NoSuchElementException&) {}
3150 }
3151}
3152
3153}
3154
3156{
3157 using namespace ::com::sun::star::ui;
3158
3159 Reference<uno::XComponentContext> xContext = ::comphelper::getProcessComponentContext();
3160 if (!xContext.is())
3161 return;
3162
3163 Reference<XModuleUIConfigurationManagerSupplier> xModuleCfgSupplier(
3164 theModuleUIConfigurationManagerSupplier::get(xContext) );
3165
3166 // Grab the Calc configuration.
3167 Reference<XUIConfigurationManager> xConfigMgr =
3168 xModuleCfgSupplier->getUIConfigurationManager(
3169 "com.sun.star.sheet.SpreadsheetDocument");
3170
3171 if (!xConfigMgr.is())
3172 return;
3173
3174 // shortcut manager
3175 Reference<XAcceleratorConfiguration> xScAccel = xConfigMgr->getShortCutManager();
3176
3177 if (!xScAccel.is())
3178 return;
3179
3180 vector<const awt::KeyEvent*> aKeys;
3181 aKeys.reserve(9);
3182
3183 // Backspace key
3184 awt::KeyEvent aBackspace;
3185 aBackspace.KeyCode = awt::Key::BACKSPACE;
3186 aBackspace.Modifiers = 0;
3187 aKeys.push_back(&aBackspace);
3188
3189 // Delete key
3190 awt::KeyEvent aDelete;
3191 aDelete.KeyCode = awt::Key::DELETE;
3192 aDelete.Modifiers = 0;
3193 aKeys.push_back(&aDelete);
3194
3195 // Ctrl-D
3196 awt::KeyEvent aCtrlD;
3197 aCtrlD.KeyCode = awt::Key::D;
3198 aCtrlD.Modifiers = awt::KeyModifier::MOD1;
3199 aKeys.push_back(&aCtrlD);
3200
3201 // Alt-Down
3202 awt::KeyEvent aAltDown;
3203 aAltDown.KeyCode = awt::Key::DOWN;
3204 aAltDown.Modifiers = awt::KeyModifier::MOD2;
3205 aKeys.push_back(&aAltDown);
3206
3207 // Ctrl-Space
3208 awt::KeyEvent aCtrlSpace;
3209 aCtrlSpace.KeyCode = awt::Key::SPACE;
3210 aCtrlSpace.Modifiers = awt::KeyModifier::MOD1;
3211 aKeys.push_back(&aCtrlSpace);
3212
3213 // Ctrl-Shift-Space
3214 awt::KeyEvent aCtrlShiftSpace;
3215 aCtrlShiftSpace.KeyCode = awt::Key::SPACE;
3216 aCtrlShiftSpace.Modifiers = awt::KeyModifier::MOD1 | awt::KeyModifier::SHIFT;
3217 aKeys.push_back(&aCtrlShiftSpace);
3218
3219 // F4
3220 awt::KeyEvent aF4;
3221 aF4.KeyCode = awt::Key::F4;
3222 aF4.Modifiers = 0;
3223 aKeys.push_back(&aF4);
3224
3225 // CTRL+SHIFT+F4
3226 awt::KeyEvent aCtrlShiftF4;
3227 aCtrlShiftF4.KeyCode = awt::Key::F4;
3228 aCtrlShiftF4.Modifiers = awt::KeyModifier::MOD1 | awt::KeyModifier::SHIFT;
3229 aKeys.push_back(&aCtrlShiftF4);
3230
3231 // SHIFT+F4
3232 awt::KeyEvent aShiftF4;
3233 aShiftF4.KeyCode = awt::Key::F4;
3234 aShiftF4.Modifiers = awt::KeyModifier::SHIFT;
3235 aKeys.push_back(&aShiftF4);
3236
3237 // Remove all involved keys first, because swapping commands don't work
3238 // well without doing this.
3239 removeKeysIfExists(xScAccel, aKeys);
3240 xScAccel->store();
3241
3242 switch (eType)
3243 {
3245 xScAccel->setKeyEvent(aDelete, ".uno:ClearContents");
3246 xScAccel->setKeyEvent(aBackspace, ".uno:Delete");
3247 xScAccel->setKeyEvent(aCtrlD, ".uno:FillDown");
3248 xScAccel->setKeyEvent(aAltDown, ".uno:DataSelect");
3249 xScAccel->setKeyEvent(aCtrlSpace, ".uno:SelectColumn");
3250 xScAccel->setKeyEvent(aCtrlShiftSpace, ".uno:SelectAll");
3251 xScAccel->setKeyEvent(aF4, ".uno:ToggleRelative");
3252 xScAccel->setKeyEvent(aCtrlShiftF4, ".uno:ViewDataSourceBrowser");
3253 break;
3255 xScAccel->setKeyEvent(aDelete, ".uno:Delete");
3256 xScAccel->setKeyEvent(aBackspace, ".uno:ClearContents");
3257 xScAccel->setKeyEvent(aCtrlD, ".uno:DataSelect");
3258 xScAccel->setKeyEvent(aCtrlShiftSpace, ".uno:SelectColumn");
3259 xScAccel->setKeyEvent(aF4, ".uno:ViewDataSourceBrowser");
3260 xScAccel->setKeyEvent(aShiftF4, ".uno:ToggleRelative");
3261 break;
3262 default:
3263 ;
3264 }
3265
3266 xScAccel->store();
3267}
3268
3270{
3271 if (!m_pSheetSaveData)
3272 return;
3273
3274 m_pSheetSaveData->UseSaveEntries(); // use positions from saved file for next saving
3275
3276 bool bHasEntries = false;
3277 SCTAB nTabCount = m_pDocument->GetTableCount();
3278 SCTAB nTab;
3279 for (nTab = 0; nTab < nTabCount; ++nTab)
3280 if (m_pSheetSaveData->HasStreamPos(nTab))
3281 bHasEntries = true;
3282
3283 if (!bHasEntries)
3284 {
3285 // if no positions were set (for example, export to other format),
3286 // reset all "valid" flags
3287 for (nTab = 0; nTab < nTabCount; ++nTab)
3288 m_pDocument->SetStreamValid(nTab, false);
3289 }
3290}
3291
3292// --- ScDocShellModificator ------------------------------------------
3293
3295 :
3296 rDocShell( rDS ),
3297 mpProtector(new ScRefreshTimerProtector(rDS.GetDocument().GetRefreshTimerControlAddress()))
3298{
3301 bIdleEnabled = rDoc.IsIdleEnabled();
3302 rDoc.SetAutoCalcShellDisabled( true );
3303 rDoc.EnableIdle(false);
3304}
3305
3307{
3311 rDocShell.SetDocumentModified(); // last one shuts off the lights
3313}
3314
3316{
3318 rDoc.PrepareFormulaCalc();
3319 if ( !rDoc.IsImportingXML() )
3320 {
3321 // temporarily restore AutoCalcShellDisabled
3322 bool bDisabled = rDoc.IsAutoCalcShellDisabled();
3325 rDoc.SetAutoCalcShellDisabled( bDisabled );
3326 }
3327 else
3328 {
3329 // uno broadcast is necessary for api to work
3330 // -> must also be done during xml import
3331 rDoc.BroadcastUno( SfxHint( SfxHintId::DataChanged ) );
3332 }
3333}
3334
3336{
3337 ScChangeTrack* pChangeTrack = m_pDocument->GetChangeTrack();
3338 return pChangeTrack != nullptr;
3339}
3340
3342{
3343 bool bRes = false;
3344 ScChangeTrack* pChangeTrack = m_pDocument->GetChangeTrack();
3345 if (pChangeTrack)
3346 bRes = pChangeTrack->IsProtected();
3347 return bRes;
3348}
3349
3350void ScDocShell::SetChangeRecording( bool bActivate, bool /*bLockAllViews*/ )
3351{
3352 bool bOldChangeRecording = IsChangeRecording();
3353
3354 if (bActivate)
3355 {
3356 m_pDocument->StartChangeTracking();
3357 ScChangeViewSettings aChangeViewSet;
3358 aChangeViewSet.SetShowChanges(true);
3359 m_pDocument->SetChangeViewSettings(aChangeViewSet);
3360 }
3361 else
3362 {
3363 m_pDocument->EndChangeTracking();
3365 }
3366
3367 if (bOldChangeRecording != IsChangeRecording())
3368 {
3370 // invalidate slots
3371 SfxBindings* pBindings = GetViewBindings();
3372 if (pBindings)
3373 pBindings->InvalidateAll(false);
3374 }
3375}
3376
3377void ScDocShell::SetProtectionPassword( const OUString &rNewPassword )
3378{
3379 ScChangeTrack* pChangeTrack = m_pDocument->GetChangeTrack();
3380 if (!pChangeTrack)
3381 return;
3382
3383 bool bProtected = pChangeTrack->IsProtected();
3384
3385 if (!rNewPassword.isEmpty())
3386 {
3387 // when password protection is applied change tracking must always be active
3388 SetChangeRecording( true );
3389
3390 css::uno::Sequence< sal_Int8 > aProtectionHash;
3391 SvPasswordHelper::GetHashPassword( aProtectionHash, rNewPassword );
3392 pChangeTrack->SetProtection( aProtectionHash );
3393 }
3394 else
3395 {
3396 pChangeTrack->SetProtection( css::uno::Sequence< sal_Int8 >() );
3397 }
3398
3399 if ( bProtected != pChangeTrack->IsProtected() )
3400 {
3403 }
3404}
3405
3406bool ScDocShell::GetProtectionHash( /*out*/ css::uno::Sequence< sal_Int8 > &rPasswordHash )
3407{
3408 bool bRes = false;
3409 ScChangeTrack* pChangeTrack = m_pDocument->GetChangeTrack();
3410 if (pChangeTrack && pChangeTrack->IsProtected())
3411 {
3412 rPasswordHash = pChangeTrack->GetProtection();
3413 bRes = true;
3414 }
3415 return bRes;
3416}
3417
3418void ScDocShell::RegisterAutomationWorkbookObject(css::uno::Reference< ooo::vba::excel::XWorkbook > const& xWorkbook)
3419{
3420 mxAutomationWorkbookObject = xWorkbook;
3421}
3422
3423extern "C" SAL_DLLPUBLIC_EXPORT bool TestImportSLK(SvStream &rStream)
3424{
3425 ScDLL::Init();
3427 ScDocOptions aDocOpt = aDocument.GetDocOptions();
3428 aDocOpt.SetLookUpColRowNames(false);
3429 aDocument.SetDocOptions(aDocOpt);
3430 aDocument.MakeTable(0);
3431 aDocument.EnableExecuteLink(false);
3432 aDocument.SetInsertingFromOtherDoc(true);
3433 aDocument.SetImportingXML(true);
3434
3435 ScImportExport aImpEx(aDocument);
3436 return aImpEx.ImportStream(rStream, OUString(), SotClipboardFormatId::SYLK);
3437}
3438
3439extern "C" SAL_DLLPUBLIC_EXPORT bool TestImportDBF(SvStream &rStream)
3440{
3441 ScDLL::Init();
3442
3443 // we need a real file for this filter
3444
3445 // put it in an empty dir
3446 utl::TempFileNamed aTmpDir(nullptr, true);
3447 aTmpDir.EnableKillingFile();
3448 OUString sTmpDir = aTmpDir.GetURL();
3449
3450 utl::TempFileNamed aTempInput(u"", true, u".dbf", &sTmpDir);
3451 aTempInput.EnableKillingFile();
3452
3453 SvStream* pInputStream = aTempInput.GetStream(StreamMode::WRITE);
3454 sal_uInt8 aBuffer[8192];
3455 while (auto nRead = rStream.ReadBytes(aBuffer, SAL_N_ELEMENTS(aBuffer)))
3456 pInputStream->WriteBytes(aBuffer, nRead);
3457 aTempInput.CloseStream();
3458
3459 SfxMedium aMedium(aTempInput.GetURL(), StreamMode::STD_READWRITE);
3460
3461 ScDocShellRef xDocShell = new ScDocShell(SfxModelFlags::EMBEDDED_OBJECT |
3462 SfxModelFlags::DISABLE_EMBEDDED_SCRIPTS |
3463 SfxModelFlags::DISABLE_DOCUMENT_RECOVERY);
3464
3465 xDocShell->DoInitNew();
3466
3467 ScDocument& rDoc = xDocShell->GetDocument();
3468
3469 ScDocOptions aDocOpt = rDoc.GetDocOptions();
3470 aDocOpt.SetLookUpColRowNames(false);
3471 rDoc.SetDocOptions(aDocOpt);
3472 rDoc.MakeTable(0);
3473 rDoc.EnableExecuteLink(false);
3474 rDoc.SetInsertingFromOtherDoc(true);
3475
3476 ScDocRowHeightUpdater::TabRanges aRecalcRanges(0, rDoc.MaxRow());
3477 std::map<SCCOL, ScColWidthParam> aColWidthParam;
3478 ErrCode eError = xDocShell->DBaseImport(aMedium.GetPhysicalName(), RTL_TEXTENCODING_IBM_850, aColWidthParam, aRecalcRanges.maRanges);
3479
3480 xDocShell->DoClose();
3481 xDocShell.clear();
3482
3483 return eError == ERRCODE_NONE;
3484}
3485
3486/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const PropertyValue * pValues
#define BCA_BRDCST_ALWAYS
Definition: address.hxx:944
SfxApplication * SfxGetpApp()
AnyEventRef aEvent
ScriptDocument aDocument
ScRecalcOptions
Definition: calcconfig.hxx:24
@ RECALC_NEVER
Definition: calcconfig.hxx:26
@ RECALC_ALWAYS
Definition: calcconfig.hxx:25
@ RECALC_ASK
Definition: calcconfig.hxx:27
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage, const ILibreOfficeKitNotifier *pNotifier=nullptr)
static weld::Window * GetDefDialogParent()
const OUString & GetValue() const
OUString GetText(LineEnd eEnd=LINEEND_LF) const
void SetText(const OUString &rStr)
bool IsWarning() const
static DialogMask HandleError(ErrCode nId, weld::Window *pParent=nullptr, DialogMask nMask=DialogMask::MAX)
void CutLastName()
OUString GetMainURL(DecodeMechanism eMechanism, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
bool HasError() const
OUString CutExtension()
OUString GetLastName(DecodeMechanism eMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
OUString GetBase() const
bool setExtension(std::u16string_view rTheExtension, sal_Int32 nIndex=LAST_SEGMENT, bool bIgnoreFinalSlash=true, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8)
bool Append(std::u16string_view rTheSegment, EncodeMechanism eMechanism=EncodeMechanism::WasEncoded, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8)
virtual CreateTabPage GetTabPageCreatorFunc(sal_uInt16 nId)=0
static SC_DLLPUBLIC ScAbstractDialogFactory * Create()
Definition: scabstdlg.cxx:37
void SetCol(SCCOL nColP)
Definition: address.hxx:291
SCROW Row() const
Definition: address.hxx:274
void SetRow(SCROW nRowP)
Definition: address.hxx:287
bool GetShowSharedDocumentWarning() const
Definition: appoptio.hxx:76
void SetShowSharedDocumentWarning(bool bNew)
Definition: appoptio.hxx:75
void SetFieldSeps(const OUString &rStr)
Definition: asciiopt.hxx:77
rtl_TextEncoding GetCharSet() const
Definition: asciiopt.hxx:57
void SetIncludeBOM(bool bVal)
Definition: asciiopt.hxx:84
void SetCharSet(rtl_TextEncoding eNew)
Definition: asciiopt.hxx:74
void ReadFromString(std::u16string_view rString)
Definition: asciiopt.cxx:88
void SetTextSep(sal_Unicode c)
Definition: asciiopt.hxx:85
OUString WriteToString() const
Definition: asciiopt.cxx:201
move ScAutoStyleHint to a different file?
Definition: hints.hxx:100
static OUString GetInputString(const ScRefCellValue &rCell, sal_uInt32 nFormat, SvNumberFormatter &rFormatter, const ScDocument &rDoc, const svl::SharedString **pShared=nullptr, bool bFiltering=false, bool bForceSystemLocale=false)
Definition: cellform.cxx:129
static OUString GetString(const ScRefCellValue &rCell, sal_uInt32 nFormat, const Color **ppColor, SvNumberFormatter &rFormatter, const ScDocument &rDoc, bool bNullVals=true, bool bFormula=false, bool bUseStarFormat=false)
Definition: cellform.cxx:31
bool IsProtected() const
Definition: chgtrack.hxx:1126
void SetProtection(const css::uno::Sequence< sal_Int8 > &rPass)
Definition: chgtrack.hxx:1122
const css::uno::Sequence< sal_Int8 > & GetProtection() const
Definition: chgtrack.hxx:1124
void SetShowChanges(bool bFlag)
Definition: chgviset.hxx:78
bool ShowChanges() const
Definition: chgviset.hxx:77
void SetShowAccepted(bool bVal)
Definition: chgviset.hxx:113
static SC_DLLPUBLIC void Init()
DLL-init/exit-code must be linked to the DLL only.
Definition: scdll.cxx:100
SC_DLLPUBLIC size_t GetCount() const
Definition: dpobject.cxx:3689
OUString CreateNewName() const
Create a new name that's not yet used by any existing data pilot objects.
Definition: dpobject.cxx:3715
void SetName(const OUString &rNew)
Definition: dpobject.cxx:490
const OUString & GetName() const
Definition: dpobject.hxx:167
size_t Count() const
Definition: detdata.hxx:78
bool HasAddError() const
Definition: detdata.hxx:77
bool DetectiveRefresh(bool bAutomatic=false)
Definition: docfunc.cxx:476
void SetLookUpColRowNames(bool bVal)
Definition: docoptio.hxx:52
Create before modifications of the document and destroy thereafter.
Definition: docsh.hxx:457
ScDocShellModificator(const ScDocShellModificator &)=delete
ScDocShell & rDocShell
Definition: docsh.hxx:458
~ScDocShellModificator() COVERITY_NOEXCEPT_FALSE
Definition: docsh.cxx:3306
bool bAutoCalcShellDisabled
Definition: docsh.hxx:460
void SetDocumentModified()
Definition: docsh.cxx:3315
Do things that need to be done before saving to our own format and necessary clean ups in dtor.
Definition: docsh.hxx:126
~PrepareSaveGuard() COVERITY_NOEXCEPT_FALSE
Definition: docsh.cxx:1747
PrepareSaveGuard(ScDocShell &rDocShell)
Definition: docsh.cxx:1723
void NotifyStyle(const SfxStyleSheetHint &rHint)
Definition: docsh4.cxx:1578
void SetInitialLinkUpdate(const SfxMedium *pMedium)
Definition: docsh4.cxx:118
SAL_DLLPRIVATE void UseSheetSaveEntries()
Definition: docsh.cxx:3269
static weld::Window * GetActiveDialogParent()
Definition: docsh.cxx:3107
ScDocShell(const ScDocShell &rDocShell)=delete
virtual bool Load(SfxMedium &rMedium) override
Definition: docsh.cxx:578
static OUString GetHtmlFilterName()
Definition: docsh.cxx:2841
void PostPaintGridAll()
Definition: docsh3.cxx:183
virtual bool Save() override
Definition: docsh.cxx:1760
double m_nPrtToScreenFactor
Definition: docsh.hxx:87
SAL_DLLPRIVATE void ResetDrawObjectShell()
Definition: docsh2.cxx:162
static OUString GetDifFilterName()
Definition: docsh.cxx:2866
void DoHardRecalc()
Definition: docsh4.cxx:1516
static OUString GetLotusFilterName()
Definition: docsh.cxx:2856
bool m_bIsInplace
Definition: docsh.hxx:93
bool MergeSharedDocument(ScDocShell *pSharedDocShell)
Definition: docsh3.cxx:1134
void SetDocumentModified()
Definition: docsh.cxx:2977
static SAL_DLLPRIVATE bool KillFile(const INetURLObject &rURL)
Definition: docsh8.cxx:186
virtual bool QuerySlotExecutable(sal_uInt16 nSlotId) override
Definition: docsh.cxx:2746
css::uno::Reference< ooo::vba::excel::XWorkbook > mxAutomationWorkbookObject
Definition: docsh.hxx:112
sal_uInt16 m_nDocumentLock
Definition: docsh.hxx:99
OUString m_aDdeTextFmt
Definition: docsh.hxx:85
SfxBindings * GetViewBindings()
Definition: docsh4.cxx:2628
bool m_bDocumentModifiedPending
Definition: docsh.hxx:96
void ErrorMessage(TranslateId pGlobStrId)
Definition: docsh5.cxx:70
std::unique_ptr< ScDocFunc > m_pDocFunc
Definition: docsh.hxx:89
static OUString GetAsciiFilterName()
Definition: docsh.cxx:2851
bool m_bHeaderOn
Definition: docsh.hxx:91
void AfterXMLLoading(bool bRet)
Definition: docsh.cxx:280
void AsciiSave(SvStream &rStream, const ScImportOptions &rOpt, SCTAB nTab)
Definition: docsh.cxx:1946
virtual bool IsChangeRecording() const override
Definition: docsh.cxx:3335
std::unique_ptr< ScOptSolverSave > m_pSolverSaveData
Definition: docsh.hxx:106
virtual void SetModified(bool=true) override
Definition: docsh.cxx:2968
void SetClipData(const css::uno::Reference< css::datatransfer::XTransferable2 > &xTransferable)
Definition: docsh.hxx:225
virtual bool HasChangeRecordProtection() const override
Definition: docsh.cxx:3341
void RegisterAutomationWorkbookObject(css::uno::Reference< ooo::vba::excel::XWorkbook > const &xWorkbook)
Definition: docsh.cxx:3418
bool IsInUndo() const
Definition: docsh.hxx:354
SAL_DLLPRIVATE SCTAB GetSaveTab()
Definition: docsh.cxx:226
css::uno::Reference< css::datatransfer::XTransferable2 > const & GetClipData() const
Definition: docsh.hxx:224
virtual bool DoSaveCompleted(SfxMedium *pNewStor=nullptr, bool bRegisterRecent=true) override
Definition: docsh.cxx:2737
void SetSolverSaveData(std::unique_ptr< ScOptSolverSave > pData)
Definition: docsh.cxx:3115
virtual bool ConvertTo(SfxMedium &rMedium) override
Definition: docsh.cxx:2375
SAL_DLLPRIVATE css::uno::Reference< css::frame::XModel > LoadSharedDocument()
std::unique_ptr< ScSheetSaveData > m_pSheetSaveData
Definition: docsh.hxx:107
std::unique_ptr< ScFormatSaveData > m_pFormatSaveData
Definition: docsh.hxx:108
bool m_bAreasChangedNeedBroadcast
Definition: docsh.hxx:98
const ScDocument & GetDocument() const
Definition: docsh.hxx:220
SAL_DLLPRIVATE void InitItems()
Definition: docsh2.cxx:94
void GetDocStat(ScDocStat &rDocStat)
Definition: docsh.cxx:3077
virtual bool PrepareClose(bool bUI=true) override
Definition: docsh.cxx:2783
virtual bool LoadFrom(SfxMedium &rMedium) override
Definition: docsh.cxx:1091
void PostDataChanged()
Definition: docsh3.cxx:93
std::shared_ptr< ScDocument > m_pDocument
Definition: docsh.hxx:83
static SAL_DLLPRIVATE bool MoveFile(const INetURLObject &rSource, const INetURLObject &rDest)
Definition: docsh8.cxx:142
static OUString GetWebQueryFilterName()
Definition: docsh.cxx:2846
std::unique_ptr< ScAutoStyleList > m_pAutoStyleList
Definition: docsh.hxx:104
SAL_DLLPRIVATE bool SaveXML(SfxMedium *pMedium, const css::uno::Reference< css::embed::XStorage > &)
Definition: docsh.cxx:562
std::unique_ptr< ScPaintLockData > m_pPaintLockData
Definition: docsh.hxx:105
ScDrawLayer * MakeDrawLayer()
Definition: docsh2.cxx:169
virtual void SetProtectionPassword(const OUString &rPassword) override
Definition: docsh.cxx:3377
SAL_DLLPRIVATE ErrCode DBaseExport(const OUString &rFullFileName, rtl_TextEncoding eCharSet, bool &bHasMemo)
Definition: docsh8.cxx:729
std::unique_ptr< DocShell_Impl > m_pImpl
Definition: docsh.hxx:88
sal_Int16 m_nCanUpdate
Definition: docsh.hxx:100
bool m_bFooterOn
Definition: docsh.hxx:92
virtual HiddenInformation GetHiddenInformationState(HiddenInformation nStates) override
Definition: docsh.cxx:238
ScTabViewShell * GetBestViewShell(bool bOnlyVisible=true)
Definition: docsh4.cxx:2609
bool m_bIsEmpty
Definition: docsh.hxx:94
void SetInUndo(bool bSet)
Definition: docsh.cxx:3072
static OUString GetDBaseFilterName()
Definition: docsh.cxx:2861
virtual bool SaveAs(SfxMedium &rMedium) override
Definition: docsh.cxx:1803
std::unique_ptr< ScDocShellModificator, o3tl::default_delete< ScDocShellModificator > > m_pModificator
Definition: docsh.hxx:110
bool IsDocumentModifiedPending() const
Definition: docsh.hxx:381
virtual void TerminateEditing() override
Definition: docsh.cxx:1797
SAL_DLLPRIVATE void InitOptions(bool bForLoading)
Definition: docsh3.cxx:403
SAL_DLLPRIVATE ErrCode DBaseImport(const OUString &rFullFileName, rtl_TextEncoding eCharSet, std::map< SCCOL, ScColWidthParam > &aColWidthParam, ScFlatBoolRowSegments &rRowHeightsRecalc)
Definition: docsh8.cxx:273
SAL_DLLPRIVATE void DoEnterHandler()
Definition: docsh.cxx:219
css::uno::Reference< css::script::vba::XVBAScriptListener > m_xVBAListener
Definition: docsh.hxx:115
SfxPrinter * GetPrinter(bool bCreateIfNotExist=true)
Definition: docsh3.cxx:451
virtual ~ScDocShell() override
Definition: docsh.cxx:2929
SAL_DLLPRIVATE bool LoadXML(SfxMedium *pMedium, const css::uno::Reference< css::embed::XStorage > &)
Definition: docsh.cxx:479
std::unique_ptr< ScDBData > m_pOldAutoDBRange
Definition: docsh.hxx:102
virtual bool ConvertFrom(SfxMedium &rMedium) override
Definition: docsh.cxx:1142
void SetDrawModified()
SetDrawModified - without Formula update.
Definition: docsh.cxx:3041
void CalcOutputFactor()
Definition: docsh3.cxx:355
virtual void SetChangeRecording(bool bActivate, bool bLockAllViews=false) override
Definition: docsh.cxx:3350
static OUString GetOwnFilterName()
Definition: docsh.cxx:2836
static ScViewData * GetViewData()
Definition: docsh4.cxx:2593
virtual bool GetProtectionHash(css::uno::Sequence< sal_Int8 > &rPasswordHash) override
Definition: docsh.cxx:3406
static bool HasAutomaticTableName(std::u16string_view rFilter)
Definition: docsh.cxx:2871
void SetDocumentModifiedPending(bool bVal)
Definition: docsh.hxx:379
SAL_DLLPRIVATE std::unique_ptr< ScDocFunc > CreateDocFunc()
Definition: docsh.cxx:2887
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
Definition: docsh.cxx:652
ScSheetSaveData * GetSheetSaveData()
Definition: docsh.cxx:3120
virtual std::set< Color > GetDocColors() override
Definition: docsh.cxx:214
ScModelObj * GetModel() const
Definition: docsh.hxx:434
void BeforeXMLLoading()
Definition: docsh.cxx:265
bool m_bIsInUndo
Definition: docsh.hxx:95
bool m_bUpdateEnabled
Definition: docsh.hxx:97
virtual std::shared_ptr< SfxDocumentInfoDialog > CreateDocumentInfoDialog(weld::Window *pParent, const SfxItemSet &rSet) override
Definition: docsh.cxx:3090
static void ResetKeyBindings(ScOptionsUtil::KeyBindingType eType)
Definition: docsh.cxx:3155
double GetOutputFactor() const
Definition: docsh.hxx:358
virtual SfxUndoManager * GetUndoManager() override
Definition: docsh.cxx:2963
ScDocFunc & GetDocFunc()
Definition: docsh.hxx:222
static SAL_DLLPRIVATE bool IsDocument(const INetURLObject &rURL)
Definition: docsh8.cxx:205
ScFormatSaveData * GetFormatSaveData()
Definition: docsh.cxx:3128
void UpdateLinks() override
Definition: docsh6.cxx:318
virtual bool LoadExternal(SfxMedium &rMedium) override
Definition: docsh.cxx:1682
SC_DLLPUBLIC sal_uInt16 GetColWidth(SCCOL nCol, SCTAB nTab, bool bHiddenAsZero=true) const
Definition: document.cxx:4187
void ClosingClipboardSource()
To be called at the clipboard document when closing a document that is the current clipboard source t...
Definition: documen2.cxx:338
bool IsIdleEnabled() const
Definition: document.hxx:2207
SC_DLLPUBLIC SCROW MaxRow() const
Definition: document.hxx:893
void PrepareFormulaCalc()
Call this before any operations that might trigger one or more formula cells to get calculated.
Definition: document.cxx:2488
SC_DLLPUBLIC void SetDocOptions(const ScDocOptions &rOpt)
Definition: documen3.cxx:1958
void EnableExecuteLink(bool bVal)
Definition: document.hxx:1602
@ TEMPORARY
normal calculation of dependencies
void EnableIdle(bool bDo)
Definition: document.hxx:2208
SC_DLLPUBLIC void MakeTable(SCTAB nTab, bool _bNeedsNameCheck=true)
Definition: document.cxx:172
void SetInsertingFromOtherDoc(bool bVal)
Definition: document.hxx:2223
sc::DocumentLinkManager & GetDocLinkManager()
Definition: documen2.cxx:241
void SetAutoCalcShellDisabled(bool bNew)
Definition: document.hxx:1414
bool IsAutoCalcShellDisabled() const
Definition: document.hxx:1415
SC_DLLPUBLIC const ScDocOptions & GetDocOptions() const
Definition: documen3.cxx:1952
bool IsImportingXML() const
Definition: document.hxx:2227
void BroadcastUno(const SfxHint &rHint)
Definition: documen3.cxx:958
Extended options held by an ScDocument containing additional settings for filters.
Definition: scextopt.hxx:77
void setAllCacheTableReferencedStati(bool bReferenced)
bool hasExternalData() const
virtual ErrCode ScExportExcel5(SfxMedium &, ScDocument *, ExportFormatExcel eFormat, rtl_TextEncoding eDest)=0
virtual ErrCode ScImportQuattroPro(SvStream *pStream, ScDocument &rDoc)=0
virtual ErrCode ScImportHTML(SvStream &, const OUString &rBaseURL, ScDocument *, ScRange &rRange, double nOutputFactor, bool bCalcWidthHeight, SvNumberFormatter *pFormatter, bool bConvertDate)=0
virtual ErrCode ScImportLotus123(SfxMedium &, ScDocument &, rtl_TextEncoding eSrc)=0
virtual void ScExportDif(SvStream &, ScDocument *, const ScAddress &rOutPos, const rtl_TextEncoding eDest)=0
virtual ErrCode ScImportRTF(SvStream &, const OUString &rBaseURL, ScDocument *, ScRange &rRange)=0
virtual ScOrcusFilters * GetOrcusFilters()=0
virtual ErrCode ScImportDif(SvStream &, ScDocument *, const ScAddress &rInsPos, const rtl_TextEncoding eSrc)=0
virtual ErrCode ScImportExcel(SfxMedium &, ScDocument *, const EXCIMPFORMAT)=0
static SC_DLLPUBLIC ScFormatFilterPlugin & Get()
Definition: impex.cxx:2675
const svl::SharedString & GetString()
FormulaError GetErrCode()
OUString GetFormula(const formula::FormulaGrammar::Grammar=formula::FormulaGrammar::GRAM_DEFAULT, const ScInterpreterContext *pContext=nullptr) const
void SetODFRecalcOptions(ScRecalcOptions eOpt)
Definition: formulaopt.hxx:64
static SC_DLLPUBLIC double nScreenPPTX
Horizontal pixel per twips factor.
Definition: global.hxx:588
static rtl_TextEncoding GetCharsetValue(std::u16string_view rCharSet)
Definition: global.cxx:568
static SC_DLLPUBLIC OUString GetDocTabName(std::u16string_view rFileName, std::u16string_view rTabName)
Definition: global2.cxx:324
static const sal_Unicode * UnicodeStrChr(const sal_Unicode *pStr, sal_Unicode c)
strchr() functionality on unicode, as long as we need it for FormulaToken etc.
Definition: global.cxx:689
::tools::Long nLastColWidthExtra
Definition: global.hxx:598
static SC_DLLPUBLIC double nScreenPPTY
Vertical pixel per twips factor.
Definition: global.hxx:590
static OUString GetCharsetString(rtl_TextEncoding eVal)
Definition: global.cxx:596
static OUString GetErrorString(FormulaError nErrNumber)
Definition: global.cxx:315
ScRefCellValue * GetNext(SCCOL &rCol, SCROW &rRow)
Definition: dociter.cxx:1092
bool IsOverflowCol() const
Definition: impex.hxx:152
void SetFormulas(bool b)
Definition: impex.hxx:135
void SetFilterOptions(const OUString &rFilterOptions)
Definition: impex.cxx:218
void SetStreamPath(const OUString &rPath)
Definition: impex.hxx:138
bool ExportStream(SvStream &, const OUString &rBaseURL, SotClipboardFormatId)
Definition: impex.cxx:433
bool IsOverflowRow() const
Definition: impex.hxx:151
bool ImportStream(SvStream &, const OUString &rBaseURL, SotClipboardFormatId)
Definition: impex.cxx:393
bool IsOverflowCell() const
Definition: impex.hxx:153
void SetExtOptions(const ScAsciiOptions &rOpt)
Definition: impex.cxx:205
const OUString & GetNonConvertibleChars() const
Definition: impex.hxx:156
bool GetIncludeBOM() const
Definition: impex.hxx:163
bool bSaveFormulas
Definition: imoptdlg.hxx:52
OUString BuildString() const
Definition: imoptdlg.cxx:103
sal_Unicode nTextSepCode
Definition: imoptdlg.hxx:45
sal_Int32 nSheetToExport
Definition: imoptdlg.hxx:58
bool bSaveNumberAsSuch
Definition: imoptdlg.hxx:51
bool bQuoteAllText
Definition: imoptdlg.hxx:50
sal_Unicode nFieldSepCode
Definition: imoptdlg.hxx:44
rtl_TextEncoding eCharSet
Definition: imoptdlg.hxx:47
todo: It should be possible to have MarkArrays for each table, in order to enable "search all" across...
Definition: markdata.hxx:43
SCTAB GetFirstSelected() const
Definition: markdata.cxx:185
void MarkToMulti()
Definition: markdata.cxx:209
void SetMarkArea(const ScRange &rRange)
Definition: markdata.cxx:92
static void CreateAndSet(ScDocShell *pDocSh)
create ScModelObj and set at pDocSh (SetBaseModel)
Definition: docuno.cxx:366
static ScDocument * GetClipDoc()
Definition: scmod.cxx:663
Collection of orcus filter wrappers.
virtual bool importXLSX(ScDocument &rDoc, SfxMedium &rMedium) const =0
virtual bool importExcel2003XML(ScDocument &rDoc, SfxMedium &rMedium) const =0
virtual bool importGnumeric(ScDocument &rDoc, SfxMedium &rMedium) const =0
virtual bool importCSV(ScDocument &rDoc, SfxMedium &rMedium) const =0
virtual bool importODS_Styles(ScDocument &rDoc, OUString &aFileName) const =0
Used to import just the styles from an xml file.
virtual bool importODS(ScDocument &rDoc, SfxMedium &rMedium) const =0
void SetStateOnPercent(sal_uInt64 nVal)
Definition: progress.hxx:96
bool GetHideFormula() const
Definition: attrib.hxx:145
bool GetHideCell() const
Definition: attrib.hxx:147
ScAddress aEnd
Definition: address.hxx:498
bool IsValid() const
Definition: address.hxx:544
ScAddress aStart
Definition: address.hxx:497
OutputDevice * GetDevice() const
Definition: sizedev.hxx:40
double GetPPTY() const
Definition: sizedev.hxx:42
double GetPPTX() const
Definition: sizedev.hxx:41
bool ExecuteRetypePassDlg(ScPasswordHash eDesiredHash)
Definition: tabvwshh.cxx:247
static ScTabViewShell * GetActiveViewShell()
Definition: tabvwsh4.cxx:1076
weld::Window * GetDialogParent()
parent window for dialogs Problem: OLE Server!
Definition: tabvwshd.cxx:31
void UpdateLayerLocks()
Definition: tabview5.cxx:351
ScViewData & GetViewData()
Definition: tabview.hxx:341
sal_uInt16 GetTablesHintId() const
Definition: uiitems.hxx:93
SCTAB GetTab1() const
Definition: uiitems.hxx:94
ScMarkData & GetMarkData()
Definition: viewdata.cxx:3141
ScDocShell * GetDocShell() const
Definition: viewdata.hxx:354
ScTabViewShell * GetViewShell() const
Definition: viewdata.hxx:357
ScDBFunc * GetView() const
Definition: viewdata.cxx:863
static bool WarningOnPassword(SfxMedium &rMedium)
Opens a query warning dialog.
bool Export(bool bStylesOnly)
Definition: xmlwrap.cxx:719
bool Import(ImportFlags nMode, ErrCode &rError)
Definition: xmlwrap.cxx:286
const sc::ImportPostProcessData & GetImportPostProcessData() const
Definition: xmlwrap.hxx:91
void RemoveDdeTopic(SfxObjectShell const *)
const DdeService * GetDdeService() const
virtual css::uno::Reference< css::document::XDocumentProperties > SAL_CALL getDocumentProperties() override
virtual void SAL_CALL storeToURL(const OUString &sURL, const css::uno::Sequence< css::beans::PropertyValue > &seqArguments) override
SfxObjectShell * GetObjectShell() const
const SfxPoolItem * ExecuteSynchron(sal_uInt16 nSlot, const SfxPoolItem **pArgs=nullptr)
void Invalidate(sal_uInt16 nId)
void InvalidateAll(bool bWithMsg)
SfxEventHintId GetEventId() const
css::uno::Reference< css::frame::XController > GetController() const
SfxHintId GetId() const
const T * GetItemIfSet(TypedWhichId< T > nWhich, bool bSrchInParent=true) const
sal_uInt16 ClearItem(sal_uInt16 nWhich=0)
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
const SfxPoolItem * GetItem(sal_uInt16 nWhich, bool bSearchInParent=true) const
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
void StartListening(SfxBroadcaster &rBroadcaster, DuplicateHandling eDuplicateHanding=DuplicateHandling::Unexpected)
void EndListening(SfxBroadcaster &rBroadcaster, bool bRemoveAllDuplicates=false)
const std::shared_ptr< const SfxFilter > & GetFilter() const
void SetError(ErrCode nError)
OUString GetBaseURL(bool bForSaving=false)
const INetURLObject & GetURLObject() const
SfxItemSet * GetItemSet() const
ErrCode GetError() const
void CloseOutStream()
const OUString & GetName() const
const css::uno::Sequence< css::beans::PropertyValue > & GetArgs() const
SvStream * GetOutStream()
bool IsStorage()
SvStream * GetInStream()
const OUString & GetPhysicalName() const
virtual bool PrepareClose(bool bUI=true)
void SetError(ErrCode rErr)
css::uno::Reference< css::script::XLibraryContainer > GetBasicContainer()
virtual bool DoSaveCompleted(SfxMedium *pNewStor=nullptr, bool bRegisterRecent=true)
virtual bool LoadFrom(SfxMedium &rMedium)
virtual bool Load(SfxMedium &rMedium)
bool IsInPrepareClose() const
OUString GetSharedFileURL() const
static bool IsOwnStorageFormat(const SfxMedium &)
virtual bool SaveAs(SfxMedium &rMedium)
bool IsEnableSetModified() const
virtual void SetVisArea(const tools::Rectangle &rVisArea)
bool SwitchToShared(bool bShared, bool bSave)
bool IsReadOnly() const
bool IsDocShared() const
virtual bool Save()
void FinishedLoading(SfxLoadedFlags nWhich=SfxLoadedFlags::ALL)
bool IsModified() const
ErrCode GetError() const
SfxMedium * GetMedium() const
void SetReadOnlyUI(bool bReadOnly=true)
bool HasSharedXMLFlagSet() const
virtual HiddenInformation GetHiddenInformationState(HiddenInformation nStates)
SfxObjectCreateMode GetCreateMode() const
static SAL_WARN_UNUSED_RESULT SfxObjectShell * Current()
virtual void SetModified(bool bModified=true)
SfxItemPool & GetPool() const
const OUString & GetName() const
SfxViewShell * GetViewShell() const
void SetPool(SfxItemPool *pNewPool)
virtual void Clear()
const css::uno::Any & GetValue() const
static SAL_WARN_UNUSED_RESULT SfxViewFrame * GetFirst(const SfxObjectShell *pDoc=nullptr, bool bOnlyVisible=true)
SfxFrame & GetFrame() const
SfxViewFrame & GetViewFrame() const
vcl::Window * GetWindow() const
bool IsTextFormat(sal_uInt32 nFIndex) const
static SVL_DLLPUBLIC void GetHashPassword(css::uno::Sequence< sal_Int8 > &rPassHash, const char *pPass, sal_uInt32 nLen)
void StartWritingUnicodeText()
void SetEndian(SvStreamEndian SvStreamEndian)
std::size_t WriteBytes(const void *pData, std::size_t nSize)
SvStream & WriteUChar(unsigned char nChar)
bool WriteUnicodeOrByteText(std::u16string_view rStr, rtl_TextEncoding eDestCharSet)
bool WriteUniOrByteChar(sal_Unicode ch, rtl_TextEncoding eDestCharSet)
SvStreamEndian GetEndian() const
sal_uInt64 Seek(sal_uInt64 nPos)
void SetStreamCharSet(rtl_TextEncoding eCharSet)
std::size_t ReadBytes(void *pData, std::size_t nSize)
rtl_TextEncoding GetStreamCharSet() const
static std::shared_ptr< ConfigurationChanges > create()
#define SO3_SC_CLASSID_60
void SetRefreshOnEmptyLine(bool bVal)
Definition: datastream.cxx:409
void setDataStream(DataStream *p)
const OUString & getString() const
LockFileEntry GetLockData()
static OUString getProductName()
void EnableKillingFile(bool bEnable=true)
SvStream * GetStream(StreamMode eMode)
OUString const & GetURL() const
static std::unique_ptr< SvStream > CreateStream(const OUString &rFileName, StreamMode eOpenMode, css::uno::Reference< css::awt::XWindow > xParentWin=nullptr)
void GrabFocus()
#define SC_COMPILER_FILE_TAB_SEP
Definition: compiler.hxx:83
int nCount
constexpr double nPPTX
constexpr double nPPTY
#define TOOLS_WARN_EXCEPTION(area, stream)
URL aURL
void UpdateAcceptChangesDialog()
Definition: docsh4.cxx:1390
constexpr OUStringLiteral pFilterDif
Definition: docsh.cxx:171
constexpr OUStringLiteral pFilterDBase
Definition: docsh.cxx:170
SAL_DLLPUBLIC_EXPORT bool TestImportSLK(SvStream &rStream)
Definition: docsh.cxx:3423
constexpr OUStringLiteral pFilterHtmlWebQ
Definition: docsh.cxx:174
SAL_DLLPUBLIC_EXPORT bool TestImportDBF(SvStream &rStream)
Definition: docsh.cxx:3439
const char pFilterEx97Temp[]
Definition: docsh.cxx:169
constexpr OUStringLiteral pFilterLotus
Definition: docsh.cxx:160
static void lcl_parseHtmlFilterOption(const OUString &rOption, LanguageType &rLang, bool &rDateConvert)
Definition: docsh.cxx:1112
const char pFilterExcel97[]
Definition: docsh.cxx:168
const char16_t pFilterSylk[]
Definition: docsh.cxx:172
constexpr OUStringLiteral pFilterSc50
Definition: docsh.cxx:158
const char pFilterEx5Temp[]
Definition: docsh.cxx:165
const char pFilterEx95Temp[]
Definition: docsh.cxx:167
const char pFilterQPro6[]
Definition: docsh.cxx:161
const char16_t pFilterRtf[]
Definition: docsh.cxx:175
const char pFilterXML[]
Definition: docsh.cxx:159
constexpr OUStringLiteral pFilterHtml
Definition: docsh.cxx:173
const char pFilterExcel5[]
Definition: docsh.cxx:164
const char16_t pFilterEx4Temp[]
Definition: docsh.cxx:163
const char pFilterExcel95[]
Definition: docsh.cxx:166
const char16_t pFilterExcel4[]
Definition: docsh.cxx:162
@ SCDOCMODE_DOCUMENT
Definition: document.hxx:256
float u
sal_Int32 nState
#define ERRCODE_IO_ABORT
#define ERRCODE_IO_CANTCREATE
#define ERRCODE_IO_GENERAL
#define SVSTREAM_FILEFORMAT_ERROR
#define ERRCODE_ABORT
#define ERRCODE_NONE
FormulaError
SfxEventHintId
Reference< XSingleServiceFactory > xFactory
#define SOFFICE_FILEFORMAT_8
#define SOFFICE_FILEFORMAT_60
ExportFormatExcel
Definition: filter.hxx:42
@ ExpBiff8
Definition: filter.hxx:42
@ ExpBiff5
Definition: filter.hxx:42
EXCIMPFORMAT
Definition: filter.hxx:39
@ EIF_BIFF8
Definition: filter.hxx:39
@ EIF_BIFF_LE4
Definition: filter.hxx:39
@ EIF_AUTO
Definition: filter.hxx:39
@ EIF_BIFF5
Definition: filter.hxx:39
DocumentType eType
SotClipboardFormatId
CellType
Definition: global.hxx:271
@ CELLTYPE_EDIT
Definition: global.hxx:276
@ CELLTYPE_STRING
Definition: global.hxx:274
@ CELLTYPE_FORMULA
Definition: global.hxx:275
@ CELLTYPE_NONE
Definition: global.hxx:272
@ CELLTYPE_VALUE
Definition: global.hxx:273
constexpr OUStringLiteral SC_TEXT_CSV_FILTER_NAME
Definition: global.hxx:63
sal_Int32 nIndex
OUString aName
void * p
sal_Int64 n
#define LANGUAGE_SYSTEM
sal_uInt16 nPos
#define SAL_WARN(area, stream)
#define SAL_N_ELEMENTS(arr)
aBuf
std::unique_ptr< sal_Int32[]> pData
const SfxItemSet * GetItemSet(const SfxPoolItem &rAttr)
SVL_DLLPUBLIC bool IsDocument(const OUString &rURL)
constexpr OUStringLiteral aData
bool needsPassHashRegen(const ScDocument &rDoc, ScPasswordHash eHash1, ScPasswordHash eHash2=PASSHASH_UNSPECIFIED)
Check for the compatibility of all password hashes.
SVL_DLLPUBLIC OUString simpleNormalizedMakeRelative(OUString const &baseUriReference, OUString const &uriReference)
OStringBuffer & padToLength(OStringBuffer &rBuffer, sal_Int32 nLength, char cFill='\0')
OUStringBuffer & truncateToLength(OUStringBuffer &rBuffer, sal_Int32 nLength)
Reference< XComponentContext > getProcessComponentContext()
css::beans::PropertyValue makePropertyValue(const OUString &rName, T &&rValue)
int i
std::shared_ptr< T > make_shared(Args &&... args)
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
SFX_IMPL_OBJECTFACTORY(DrawDocShell, SvGlobalName(SO3_SIMPRESS_CLASSID), "simpress") void DrawDocShell
sal_Int32 toInt32(std::u16string_view rStr)
HiddenInformation
OUString ScResId(TranslateId aId)
Definition: scdll.cxx:90
#define SCWARN_EXPORT_ASCII
Definition: scerrors.hxx:71
#define SCWARN_IMPORT_ROW_OVERFLOW
Definition: scerrors.hxx:62
#define SCERR_IMPORT_UNKNOWN
Definition: scerrors.hxx:27
#define SCWARN_IMPORT_CELL_OVERFLOW
Definition: scerrors.hxx:65
#define SCERR_EXPORT_DATA
Definition: scerrors.hxx:53
#define SCWARN_IMPORT_COLUMN_OVERFLOW
Definition: scerrors.hxx:63
#define SCERR_IMPORT_CONNECT
Definition: scerrors.hxx:25
#define SCERR_IMPORT_NI
Definition: scerrors.hxx:35
#define SCWARN_EXPORT_NONCONVERTIBLE_CHARS
Definition: scerrors.hxx:69
constexpr TypedWhichId< SvxHorJustifyItem > ATTR_HOR_JUSTIFY(129)
constexpr TypedWhichId< ScProtectionAttr > ATTR_PROTECTION(149)
#define SC_MOD()
Definition: scmod.hxx:249
#define ERRCODE_SFX_WRONGPASSWORD
SfxModelFlags
static SfxItemSet & rSet
#define SFX_IMPL_INTERFACE(Class, SuperClass)
OUString VCL_DLLPUBLIC GetStandardText(StandardButtonType eButton)
TOOLS_DLLPUBLIC SvStream & endlub(SvStream &rStr)
SvStreamEndian
TOOLS_DLLPUBLIC std::size_t write_uInt16s_FromOUString(SvStream &rStrm, std::u16string_view rStr, std::size_t nUnits)
ScFlatBoolRowSegments maRanges
Definition: dociter.hxx:447
sal_uInt16 nPageCount
Definition: document.hxx:290
SCTAB nTableCount
Definition: document.hxx:287
This is very similar to ScCellValue, except that it references the original value instead of copying ...
Definition: cellvalue.hxx:108
ScFormulaCell * getFormula() const
Definition: cellvalue.hxx:137
const EditTextObject * getEditText() const
Definition: cellvalue.hxx:136
const svl::SharedString * getSharedString() const
Definition: cellvalue.hxx:135
CellType getType() const
Definition: cellvalue.hxx:133
Data stream data needs to be post-processed because it requires ScDocShell instance which is not avai...
Stores data imported from the file that need to be processed at the end of the import process.
std::unique_ptr< DataStream > mpDataStream
Reference< XController > xController
Reference< XModel > xModel
SvxCellHorJustify
@ PASSHASH_XL
@ PASSHASH_SHA1
@ PASSHASH_SHA256
unsigned char sal_uInt8
sal_uInt16 sal_Unicode
sal_Int16 SCTAB
Definition: types.hxx:22
sal_Int16 SCCOL
Definition: types.hxx:21
sal_Int32 SCROW
Definition: types.hxx:17
#define SC_TAB_INSERTED
Definition: uiitems.hxx:75
const sal_Unicode cDelim
Definition: unitconv.cxx:29
RET_CANCEL
RET_NO
RET_RETRY
RET_YES
std::unique_ptr< weld::CheckButton > m_xWarningOnBox
std::unique_ptr< char[]> aBuffer