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