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