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 <docsh.hxx>
21
22#include <config_features.h>
23#include <scitems.hxx>
24#include <sc.hrc>
25#include <vcl/errinf.hxx>
31#include <vcl/stdtext.hxx>
32#include <vcl/syswin.hxx>
33#include <vcl/svapp.hxx>
34#include <vcl/virdev.hxx>
35#include <vcl/weld.hxx>
36#include <rtl/bootstrap.hxx>
37#include <rtl/tencinfo.h>
38#include <sal/log.hxx>
40#include <sfx2/app.hxx>
41#include <sfx2/bindings.hxx>
42#include <sfx2/dinfdlg.hxx>
43#include <sfx2/docfile.hxx>
44#include <sfx2/event.hxx>
45#include <sfx2/docfilt.hxx>
46#include <sfx2/objface.hxx>
47#include <sfx2/viewfrm.hxx>
49#include <svl/fstathelper.hxx>
51#include <svl/urihelper.hxx>
52#include <osl/file.hxx>
53#include <chgtrack.hxx>
54#include <chgviset.hxx>
55#include <com/sun/star/awt/Key.hpp>
56#include <com/sun/star/awt/KeyModifier.hpp>
57#include <com/sun/star/container/XContentEnumerationAccess.hpp>
58#include <com/sun/star/document/UpdateDocMode.hpp>
59#include <com/sun/star/script/vba/VBAEventId.hpp>
60#include <com/sun/star/script/vba/VBAScriptEventId.hpp>
61#include <com/sun/star/script/vba/XVBAEventProcessor.hpp>
62#include <com/sun/star/script/vba/XVBAScriptListener.hpp>
63#include <com/sun/star/script/vba/XVBACompatibility.hpp>
64#include <com/sun/star/sheet/XSpreadsheetView.hpp>
65#include <com/sun/star/task/XJob.hpp>
66#include <com/sun/star/ui/theModuleUIConfigurationManagerSupplier.hpp>
67#include <com/sun/star/ui/XAcceleratorConfiguration.hpp>
68#include <com/sun/star/util/VetoException.hpp>
69#include <com/sun/star/lang/XSingleComponentFactory.hpp>
70#include <ooo/vba/excel/XWorkbook.hpp>
71#include <tools/diagnose_ex.h>
72
73#include <config_folders.h>
74
75#include <scabstdlg.hxx>
76#include <sot/formats.hxx>
77#include <svx/dialogs.hrc>
78
79#include <formulacell.hxx>
80#include <global.hxx>
81#include <filter.hxx>
82#include <scmod.hxx>
83#include <tabvwsh.hxx>
84#include <docfunc.hxx>
85#include <imoptdlg.hxx>
86#include <impex.hxx>
87#include <scresid.hxx>
88#include <strings.hrc>
89#include <globstr.hrc>
90#include <scerrors.hxx>
91#include <brdcst.hxx>
92#include <stlpool.hxx>
93#include <autostyl.hxx>
94#include <attrib.hxx>
95#include <asciiopt.hxx>
96#include <progress.hxx>
97#include <pntlock.hxx>
98#include <docuno.hxx>
99#include <appoptio.hxx>
100#include <formulaopt.hxx>
101#include <scdll.hxx>
102#include <detdata.hxx>
103#include <printfun.hxx>
104#include <dociter.hxx>
105#include <cellform.hxx>
106#include <chartlis.hxx>
107#include <hints.hxx>
108#include <xmlwrap.hxx>
109#include <drwlayer.hxx>
110#include <dbdata.hxx>
111#include <scextopt.hxx>
112#include <compiler.hxx>
113#include <warnpassword.hxx>
114#include <optsolver.hxx>
115#include <sheetdata.hxx>
116#include <tabprotection.hxx>
117#include <docparam.hxx>
118#include "docshimp.hxx"
119#include <sizedev.hxx>
121
122#include <officecfg/Office/Calc.hxx>
124#include <comphelper/string.hxx>
125#include <unotools/configmgr.hxx>
126#include <unotools/tempfile.hxx>
128#include <uiitems.hxx>
129#include <dpobject.hxx>
130#include <markdata.hxx>
131#include <docoptio.hxx>
132#include <orcusfilters.hxx>
133#include <datastream.hxx>
134#include <documentlinkmgr.hxx>
135#include <refupdatecontext.hxx>
136
137#include <memory>
138#include <vector>
139
140#include <comphelper/lok.hxx>
141#include <svtools/sfxecode.hxx>
143
144using namespace com::sun::star;
145using ::com::sun::star::uno::Reference;
146using ::com::sun::star::lang::XMultiServiceFactory;
147using std::shared_ptr;
148using ::std::vector;
149
150// Filter names (like in sclib.cxx)
151
152constexpr OUStringLiteral pFilterSc50 = u"StarCalc 5.0";
153const char pFilterXML[] = "StarOffice XML (Calc)";
154constexpr OUStringLiteral pFilterLotus = u"Lotus";
155const char pFilterQPro6[] = "Quattro Pro 6.0";
156const char16_t pFilterExcel4[] = u"MS Excel 4.0";
157const char16_t pFilterEx4Temp[] = u"MS Excel 4.0 Vorlage/Template";
158const char pFilterExcel5[] = "MS Excel 5.0/95";
159const char pFilterEx5Temp[] = "MS Excel 5.0/95 Vorlage/Template";
160const char pFilterExcel95[] = "MS Excel 95";
161const char pFilterEx95Temp[] = "MS Excel 95 Vorlage/Template";
162const char pFilterExcel97[] = "MS Excel 97";
163const char pFilterEx97Temp[] = "MS Excel 97 Vorlage/Template";
164constexpr OUStringLiteral pFilterDBase = u"dBase";
165constexpr OUStringLiteral pFilterDif = u"DIF";
166const char16_t pFilterSylk[] = u"SYLK";
167constexpr OUStringLiteral pFilterHtml = u"HTML (StarCalc)";
168constexpr OUStringLiteral pFilterHtmlWebQ = u"calc_HTML_WebQuery";
169const char16_t pFilterRtf[] = u"Rich Text Format (StarCalc)";
170
171#define ShellClass_ScDocShell
172#include <scslots.hxx>
173
175
176void ScDocShell::InitInterface_Impl()
177{
178}
179
180// GlobalName of the current version:
181SFX_IMPL_OBJECTFACTORY( ScDocShell, SvGlobalName(SO3_SC_CLASSID), "scalc" )
182
183
184void ScDocShell::FillClass( SvGlobalName* pClassName,
185 SotClipboardFormatId* pFormat,
186 OUString* pFullTypeName,
187 sal_Int32 nFileFormat,
188 bool bTemplate /* = false */) const
189{
190 if ( nFileFormat == SOFFICE_FILEFORMAT_60 )
191 {
192 *pClassName = SvGlobalName( SO3_SC_CLASSID_60 );
193 *pFormat = SotClipboardFormatId::STARCALC_60;
194 *pFullTypeName = ScResId( SCSTR_LONG_SCDOC_NAME_60 );
195 }
196 else if ( nFileFormat == SOFFICE_FILEFORMAT_8 )
197 {
198 *pClassName = SvGlobalName( SO3_SC_CLASSID_60 );
199 *pFormat = bTemplate ? SotClipboardFormatId::STARCALC_8_TEMPLATE : SotClipboardFormatId::STARCALC_8;
200 *pFullTypeName = ScResId( SCSTR_LONG_SCDOC_NAME_80 );
201 }
202 else
203 {
204 OSL_FAIL("Which version?");
205 }
206}
207
209{
210 return m_pDocument->GetDocColors();
211}
212
214{
216 if (pViewSh && pViewSh->GetViewData().GetDocShell() == this)
217 SC_MOD()->InputEnterHandler();
218}
219
221{
222 SCTAB nTab = 0;
224 if (pSh)
225 {
226 const ScMarkData& rMark = pSh->GetViewData().GetMarkData();
227 nTab = rMark.GetFirstSelected();
228 }
229 return nTab;
230}
231
233{
234 // get global state like HiddenInformation::DOCUMENTVERSIONS
236
237 if ( nStates & HiddenInformation::RECORDEDCHANGES )
238 {
239 if ( m_pDocument->GetChangeTrack() && m_pDocument->GetChangeTrack()->GetFirst() )
240 nState |= HiddenInformation::RECORDEDCHANGES;
241 }
242 if ( nStates & HiddenInformation::NOTES )
243 {
244 SCTAB nTableCount = m_pDocument->GetTableCount();
245 bool bFound = false;
246 for (SCTAB nTab = 0; nTab < nTableCount && !bFound; ++nTab)
247 {
248 if (m_pDocument->HasTabNotes(nTab)) //TODO:
249 bFound = true;
250 }
251
252 if (bFound)
253 nState |= HiddenInformation::NOTES;
254 }
255
256 return nState;
257}
258
260{
261 m_pDocument->EnableIdle(false);
262
263 // prevent unnecessary broadcasts and updates
264 OSL_ENSURE(m_pModificator == nullptr, "The Modificator should not exist");
265 m_pModificator.reset( new ScDocShellModificator( *this ) );
266
267 m_pDocument->SetImportingXML( true );
268 m_pDocument->EnableExecuteLink( false ); // #i101304# to be safe, prevent nested loading from external references
269 m_pDocument->EnableUndo( false );
270 // prevent unnecessary broadcasts and "half way listeners"
271 m_pDocument->SetInsertingFromOtherDoc( true );
272}
273
275{
276 if (GetCreateMode() != SfxObjectCreateMode::ORGANIZER)
277 {
278 UpdateLinks();
279 // don't prevent establishing of listeners anymore
280 m_pDocument->SetInsertingFromOtherDoc( false );
281 if ( bRet )
282 {
283 ScChartListenerCollection* pChartListener = m_pDocument->GetChartListenerCollection();
284 if (pChartListener)
285 pChartListener->UpdateDirtyCharts();
286
287 // #95582#; set the table names of linked tables to the new path
288 SCTAB nTabCount = m_pDocument->GetTableCount();
289 for (SCTAB i = 0; i < nTabCount; ++i)
290 {
291 if (m_pDocument->IsLinked( i ))
292 {
293 OUString aName;
294 m_pDocument->GetName(i, aName);
295 OUString aLinkTabName = m_pDocument->GetLinkTab(i);
296 sal_Int32 nLinkTabNameLength = aLinkTabName.getLength();
297 sal_Int32 nNameLength = aName.getLength();
298 if (nLinkTabNameLength < nNameLength)
299 {
300
301 // remove the quotes on begin and end of the docname and restore the escaped quotes
302 const sal_Unicode* pNameBuffer = aName.getStr();
303 if ( *pNameBuffer == '\'' && // all docnames have to have a ' character on the first pos
305 {
306 OUStringBuffer aDocURLBuffer;
307 bool bQuote = true; // Document name is always quoted
308 ++pNameBuffer;
309 while ( bQuote && *pNameBuffer )
310 {
311 if ( *pNameBuffer == '\'' && *(pNameBuffer-1) != '\\' )
312 bQuote = false;
313 else if( *pNameBuffer != '\\' || *(pNameBuffer+1) != '\'' )
314 aDocURLBuffer.append(*pNameBuffer); // If escaped quote: only quote in the name
315 ++pNameBuffer;
316 }
317
318 if( *pNameBuffer == SC_COMPILER_FILE_TAB_SEP ) // after the last quote of the docname should be the # char
319 {
320 sal_Int32 nIndex = nNameLength - nLinkTabNameLength;
321 INetURLObject aINetURLObject(aDocURLBuffer);
322 if(aName.match( aLinkTabName, nIndex) &&
323 (aName[nIndex - 1] == '#') && // before the table name should be the # char
324 !aINetURLObject.HasError()) // the docname should be a valid URL
325 {
326 aName = ScGlobal::GetDocTabName( m_pDocument->GetLinkDoc( i ), m_pDocument->GetLinkTab( i ) );
327 m_pDocument->RenameTab(i, aName, true/*bExternalDocument*/);
328 }
329 // else; nothing has to happen, because it is a user given name
330 }
331 // else; nothing has to happen, because it is a user given name
332 }
333 // else; nothing has to happen, because it is a user given name
334 }
335 // else; nothing has to happen, because it is a user given name
336 }
337 }
338
339 // #i94570# DataPilot table names have to be unique, or the tables can't be accessed by API.
340 // If no name (or an invalid name, skipped in ScXMLDataPilotTableContext::EndElement) was set, create a new name.
341 ScDPCollection* pDPCollection = m_pDocument->GetDPCollection();
342 if ( pDPCollection )
343 {
344 size_t nDPCount = pDPCollection->GetCount();
345 for (size_t nDP=0; nDP<nDPCount; ++nDP)
346 {
347 ScDPObject& rDPObj = (*pDPCollection)[nDP];
348 if (rDPObj.GetName().isEmpty())
349 rDPObj.SetName( pDPCollection->CreateNewName() );
350 }
351 }
352 }
353 }
354 else
355 m_pDocument->SetInsertingFromOtherDoc( false );
356
357 m_pDocument->SetImportingXML( false );
358 m_pDocument->EnableExecuteLink( true );
359 m_pDocument->EnableUndo( true );
360 m_bIsEmpty = false;
361
362 if (m_pModificator)
363 {
364 ScDocument::HardRecalcState eRecalcState = m_pDocument->GetHardRecalcState();
365 // Temporarily set hard-recalc to prevent calling
366 // ScFormulaCell::Notify() during destruction of the Modificator which
367 // will set the cells dirty.
368 if (eRecalcState == ScDocument::HardRecalcState::OFF)
370 m_pModificator.reset();
371 m_pDocument->SetHardRecalcState(eRecalcState);
372 }
373 else
374 {
375 OSL_FAIL("The Modificator should exist");
376 }
377
378 m_pDocument->EnableIdle(true);
379}
380
381namespace {
382
383class LoadMediumGuard
384{
385public:
386 explicit LoadMediumGuard(ScDocument* pDoc) :
387 mpDoc(pDoc)
388 {
389 mpDoc->SetLoadingMedium(true);
390 }
391
392 ~LoadMediumGuard()
393 {
394 mpDoc->SetLoadingMedium(false);
395 }
396private:
397 ScDocument* mpDoc;
398};
399
400void processDataStream( ScDocShell& rShell, const sc::ImportPostProcessData& rData )
401{
402 if (!rData.mpDataStream)
403 return;
404
405 const sc::ImportPostProcessData::DataStream& r = *rData.mpDataStream;
406 if (!r.maRange.IsValid())
407 return;
408
409 // Break the streamed range into the top range and the height limit. A
410 // height limit of 0 means unlimited i.e. the streamed data will go all
411 // the way to the last row.
412
413 ScRange aTopRange = r.maRange;
414 aTopRange.aEnd.SetRow(aTopRange.aStart.Row());
415 sal_Int32 nLimit = r.maRange.aEnd.Row() - r.maRange.aStart.Row() + 1;
416 if (r.maRange.aEnd.Row() == rShell.GetDocument().MaxRow())
417 // Unlimited range.
418 nLimit = 0;
419
423
424 sc::DataStream* pStrm = new sc::DataStream(&rShell, r.maURL, aTopRange, nLimit, eMove, 0);
427 rMgr.setDataStream(pStrm);
428}
429
430class MessageWithCheck : public weld::MessageDialogController
431{
432private:
433 std::unique_ptr<weld::CheckButton> m_xWarningOnBox;
434public:
435 MessageWithCheck(weld::Window *pParent, const OUString& rUIFile, const OString& rDialogId)
436 : MessageDialogController(pParent, rUIFile, rDialogId, "ask")
437 , m_xWarningOnBox(m_xBuilder->weld_check_button("ask"))
438 {
439 }
440 bool get_active() const { return m_xWarningOnBox->get_active(); }
441 void hide_ask() const { m_xWarningOnBox->set_visible(false); };
442};
443
444#if HAVE_FEATURE_SCRIPTING
445class VBAScriptListener : public ::cppu::WeakImplHelper< css::script::vba::XVBAScriptListener >
446{
447private:
448 ScDocShell* m_pDocSh;
449public:
450 VBAScriptListener(ScDocShell* pDocSh) : m_pDocSh(pDocSh)
451 {
452 }
453
454 // XVBAScriptListener
455 virtual void SAL_CALL notifyVBAScriptEvent( const ::css::script::vba::VBAScriptEvent& aEvent ) override
456 {
457 if (aEvent.Identifier == script::vba::VBAScriptEventId::SCRIPT_STOPPED &&
458 m_pDocSh->GetClipData().is())
459 {
460 m_pDocSh->SetClipData(uno::Reference<datatransfer::XTransferable2>());
461 }
462 }
463
464 // XEventListener
465 virtual void SAL_CALL disposing( const ::css::lang::EventObject& /*Source*/ ) override
466 {
467 }
468};
469#endif
470
471}
472
473bool ScDocShell::LoadXML( SfxMedium* pLoadMedium, const css::uno::Reference< css::embed::XStorage >& xStor )
474{
475 LoadMediumGuard aLoadGuard(m_pDocument.get());
476
477 // MacroCallMode is no longer needed, state is kept in SfxObjectShell now
478
479 // no Seek(0) here - always loading from storage, GetInStream must not be called
480
482
483 ScXMLImportWrapper aImport(*this, pLoadMedium, xStor);
484
485 bool bRet = false;
486 ErrCode nError = ERRCODE_NONE;
487 m_pDocument->LockAdjustHeight();
488 if (GetCreateMode() == SfxObjectCreateMode::ORGANIZER)
489 bRet = aImport.Import(ImportFlags::Styles, nError);
490 else
491 bRet = aImport.Import(ImportFlags::All, nError);
492
493 if ( nError )
494 pLoadMedium->SetError(nError);
495
496 processDataStream(*this, aImport.GetImportPostProcessData());
497
498 //if the document was not generated by LibreOffice, do hard recalc in case some other document
499 //generator saved cached formula results that differ from LibreOffice's calculated results or
500 //did not use cached formula results.
501 uno::Reference<document::XDocumentPropertiesSupplier> xDPS(GetModel(), uno::UNO_QUERY_THROW);
502 uno::Reference<document::XDocumentProperties> xDocProps = xDPS->getDocumentProperties();
503
504 ScRecalcOptions nRecalcMode =
505 static_cast<ScRecalcOptions>(officecfg::Office::Calc::Formula::Load::ODFRecalcMode::get());
506
507 bool bHardRecalc = false;
508 if (nRecalcMode == RECALC_ASK)
509 {
510 OUString sProductName(utl::ConfigManager::getProductName());
511 if (m_pDocument->IsUserInteractionEnabled() && xDocProps->getGenerator().indexOf(sProductName) == -1)
512 {
513 // Generator is not LibreOffice. Ask if the user wants to perform
514 // full re-calculation.
515 MessageWithCheck aQueryBox(GetActiveDialogParent(),
516 "modules/scalc/ui/recalcquerydialog.ui", "RecalcQueryDialog");
517 aQueryBox.set_primary_text(ScResId(STR_QUERY_FORMULA_RECALC_ONLOAD_ODS));
518 aQueryBox.set_default_response(RET_YES);
519
520 if ( officecfg::Office::Calc::Formula::Load::OOXMLRecalcMode::isReadOnly() )
521 aQueryBox.hide_ask();
522
523 bHardRecalc = aQueryBox.run() == RET_YES;
524
525 if (aQueryBox.get_active())
526 {
527 // Always perform selected action in the future.
528 std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
529 officecfg::Office::Calc::Formula::Load::ODFRecalcMode::set(sal_Int32(0), batch);
530 ScFormulaOptions aOpt = SC_MOD()->GetFormulaOptions();
531 aOpt.SetODFRecalcOptions(bHardRecalc ? RECALC_ALWAYS : RECALC_NEVER);
532 /* XXX is this really supposed to set the ScModule options?
533 * Not the ScDocShell options? */
534 SC_MOD()->SetFormulaOptions(aOpt);
535
536 batch->commit();
537 }
538 }
539 }
540 else if (nRecalcMode == RECALC_ALWAYS)
541 bHardRecalc = true;
542
543 if (bHardRecalc)
544 DoHardRecalc();
545 else
546 {
547 // still need to recalc volatile formula cells.
548 m_pDocument->Broadcast(ScHint(SfxHintId::ScDataChanged, BCA_BRDCST_ALWAYS));
549 }
550
551 AfterXMLLoading(bRet);
552
553 m_pDocument->UnlockAdjustHeight();
554 return bRet;
555}
556
557bool ScDocShell::SaveXML( SfxMedium* pSaveMedium, const css::uno::Reference< css::embed::XStorage >& xStor )
558{
559 m_pDocument->EnableIdle(false);
560
561 ScXMLImportWrapper aImport(*this, pSaveMedium, xStor);
562 bool bRet(false);
563 if (GetCreateMode() != SfxObjectCreateMode::ORGANIZER)
564 bRet = aImport.Export(false);
565 else
566 bRet = aImport.Export(true);
567
568 m_pDocument->EnableIdle(true);
569
570 return bRet;
571}
572
574{
575 LoadMediumGuard aLoadGuard(m_pDocument.get());
576 ScRefreshTimerProtector aProt( m_pDocument->GetRefreshTimerControlAddress() );
577
578 // only the latin script language is loaded
579 // -> initialize the others from options (before loading)
580 InitOptions(true);
581
582 // If this is an ODF file being loaded, then by default, use legacy processing
583 // for tdf#99729 (if required, it will be overridden in *::ReadUserDataSequence())
584 if (IsOwnStorageFormat(rMedium))
585 {
586 if (m_pDocument->GetDrawLayer())
587 m_pDocument->GetDrawLayer()->SetAnchoredTextOverflowLegacy(true);
588 }
589
591
592 bool bRet = SfxObjectShell::Load(rMedium);
593 if (bRet)
594 {
595 SetInitialLinkUpdate(&rMedium);
596
597 {
598 // prepare a valid document for XML filter
599 // (for ConvertFrom, InitNew is called before)
600 m_pDocument->MakeTable(0);
601 m_pDocument->GetStyleSheetPool()->CreateStandardStyles();
602 m_pDocument->UpdStlShtPtrsFrmNms();
603
604 if (!m_bUcalcTest)
605 {
606 /* Create styles that are imported through Orcus */
607
608 OUString aURL("$BRAND_BASE_DIR/" LIBO_SHARE_FOLDER "/calc/styles.xml");
609 rtl::Bootstrap::expandMacros(aURL);
610
611 OUString aPath;
612 osl::FileBase::getSystemPathFromFileURL(aURL, aPath);
613
615
616 if (pOrcus)
617 {
618 pOrcus->importODS_Styles(*m_pDocument, aPath);
619 m_pDocument->GetStyleSheetPool()->setAllParaStandard();
620 }
621 }
622
623 bRet = LoadXML( &rMedium, nullptr );
624 }
625 }
626
627 if (!bRet && !rMedium.GetError())
629
630 if (rMedium.GetError())
631 SetError(rMedium.GetError());
632
633 InitItems();
635
636 // invalidate eventually temporary table areas
637 if ( bRet )
638 m_pDocument->InvalidateTableArea();
639
640 m_bIsEmpty = false;
642 return bRet;
643}
644
646{
647 const ScTablesHint* pScHint = dynamic_cast< const ScTablesHint* >( &rHint );
648 if (pScHint)
649 {
650 if (pScHint->GetTablesHintId() == SC_TAB_INSERTED)
651 {
652 uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents = m_pDocument->GetVbaEventProcessor();
653 if ( xVbaEvents.is() ) try
654 {
655 uno::Sequence< uno::Any > aArgs{ uno::Any(pScHint->GetTab1()) };
656 xVbaEvents->processVbaEvent( script::vba::VBAEventId::WORKBOOK_NEWSHEET, aArgs );
657 }
658 catch( uno::Exception& )
659 {
660 }
661 }
662 }
663
664 if ( auto pStyleSheetHint = dynamic_cast<const SfxStyleSheetHint*>(&rHint) ) // Template changed
665 NotifyStyle( *pStyleSheetHint );
666 else if ( auto pStlHint = dynamic_cast<const ScAutoStyleHint*>(&rHint) )
667 {
669
670 // this is called synchronously from ScInterpreter::ScStyle,
671 // modifying the document must be asynchronous
672 // (handled by AddInitial)
673
674 const ScRange& aRange = pStlHint->GetRange();
675 const OUString& aName1 = pStlHint->GetStyle1();
676 const OUString& aName2 = pStlHint->GetStyle2();
677 sal_uInt32 nTimeout = pStlHint->GetTimeout();
678
679 if (!m_pAutoStyleList)
680 m_pAutoStyleList.reset( new ScAutoStyleList(this) );
681 m_pAutoStyleList->AddInitial( aRange, aName1, nTimeout, aName2 );
682 }
683 else if ( auto pEventHint = dynamic_cast<const SfxEventHint*>(&rHint) )
684 {
685 SfxEventHintId nEventId = pEventHint->GetEventId();
686
687 switch ( nEventId )
688 {
689 case SfxEventHintId::LoadFinished:
690 {
691#if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
692 // the readonly documents should not be opened in shared mode
693 if ( HasSharedXMLFlagSet() && !SC_MOD()->IsInSharedDocLoading() && !IsReadOnly() )
694 {
695 if ( SwitchToShared( true, false ) )
696 {
697 ScViewData* pViewData = GetViewData();
698 ScTabView* pTabView = ( pViewData ? pViewData->GetView() : nullptr );
699 if ( pTabView )
700 {
701 pTabView->UpdateLayerLocks();
702 }
703 }
704 else
705 {
706 // switching to shared mode has failed, the document should be opened readonly
707 // TODO/LATER: And error message should be shown here probably
709 }
710 }
711#endif
712 }
713 break;
714 case SfxEventHintId::ViewCreated:
715 {
716 #if HAVE_FEATURE_SCRIPTING
717 uno::Reference<script::vba::XVBACompatibility> xVBACompat(GetBasicContainer(), uno::UNO_QUERY);
718 if ( !m_xVBAListener.is() && xVBACompat.is() )
719 {
720 m_xVBAListener.set(new VBAScriptListener(this));
721 xVBACompat->addVBAScriptListener(m_xVBAListener);
722 }
723#endif
724
725#if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
726 if ( IsDocShared() && !SC_MOD()->IsInSharedDocLoading() )
727 {
728 ScAppOptions aAppOptions = SC_MOD()->GetAppOptions();
729 if ( aAppOptions.GetShowSharedDocumentWarning() )
730 {
731 MessageWithCheck aWarningBox(ScDocShell::GetActiveDialogParent(),
732 "modules/scalc/ui/sharedwarningdialog.ui", "SharedWarningDialog");
733 aWarningBox.run();
734
735 bool bChecked = aWarningBox.get_active();
736 if (bChecked)
737 {
738 aAppOptions.SetShowSharedDocumentWarning(false);
739 SC_MOD()->SetAppOptions( aAppOptions );
740 }
741 }
742 }
743#endif
744 try
745 {
746 uno::Reference< uno::XComponentContext > xContext(
748 uno::Reference< lang::XMultiServiceFactory > xServiceManager(
749 xContext->getServiceManager(),
750 uno::UNO_QUERY_THROW );
751 uno::Reference< container::XContentEnumerationAccess > xEnumAccess( xServiceManager, uno::UNO_QUERY_THROW );
752 uno::Reference< container::XEnumeration> xEnum = xEnumAccess->createContentEnumeration(
753 "com.sun.star.sheet.SpreadsheetDocumentJob" );
754 if ( xEnum.is() )
755 {
756 while ( xEnum->hasMoreElements() )
757 {
758 uno::Any aAny = xEnum->nextElement();
759 uno::Reference< lang::XSingleComponentFactory > xFactory;
760 aAny >>= xFactory;
761 if ( xFactory.is() )
762 {
763 uno::Reference< task::XJob > xJob( xFactory->createInstanceWithContext( xContext ), uno::UNO_QUERY_THROW );
764 ScViewData* pViewData = GetViewData();
765 SfxViewShell* pViewShell = ( pViewData ? pViewData->GetViewShell() : nullptr );
766 SfxViewFrame* pViewFrame = ( pViewShell ? pViewShell->GetViewFrame() : nullptr );
767 SfxFrame* pFrame = ( pViewFrame ? &pViewFrame->GetFrame() : nullptr );
768 uno::Reference< frame::XController > xController = ( pFrame ? pFrame->GetController() : nullptr );
769 uno::Reference< sheet::XSpreadsheetView > xSpreadsheetView( xController, uno::UNO_QUERY_THROW );
770 uno::Sequence< beans::NamedValue > aArgsForJob { { "SpreadsheetView", uno::Any( xSpreadsheetView ) } };
771 xJob->execute( aArgsForJob );
772 }
773 }
774 }
775 }
776 catch ( uno::Exception & )
777 {
778 }
779 }
780 break;
781 case SfxEventHintId::SaveDoc:
782 {
783#if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
784 if ( IsDocShared() && !SC_MOD()->IsInSharedDocSaving() )
785 {
786 bool bSuccess = false;
787 bool bRetry = true;
788 while ( bRetry )
789 {
790 bRetry = false;
791 uno::Reference< frame::XModel > xModel;
792 try
793 {
794 // load shared file
795 xModel.set( LoadSharedDocument(), uno::UNO_SET_THROW );
796 uno::Reference< util::XCloseable > xCloseable( xModel, uno::UNO_QUERY_THROW );
797
798 // check if shared flag is set in shared file
799 bool bShared = false;
800 ScModelObj* pDocObj = comphelper::getFromUnoTunnel<ScModelObj>( xModel );
801 ScDocShell* pSharedDocShell = ( pDocObj ? dynamic_cast< ScDocShell* >( pDocObj->GetObjectShell() ) : nullptr );
802 if ( pSharedDocShell )
803 {
804 bShared = pSharedDocShell->HasSharedXMLFlagSet();
805 }
806
807 // #i87870# check if shared status was disabled and enabled again
808 bool bOwnEntry = false;
809 bool bEntriesNotAccessible = false;
810 try
811 {
813 bOwnEntry = aControlFile.HasOwnEntry();
814 }
815 catch ( uno::Exception& )
816 {
817 bEntriesNotAccessible = true;
818 }
819
820 if ( bShared && bOwnEntry )
821 {
822 uno::Reference< frame::XStorable > xStorable( xModel, uno::UNO_QUERY_THROW );
823
824 if ( xStorable->isReadonly() )
825 {
826 xCloseable->close( true );
827
828 OUString aUserName( ScResId( STR_UNKNOWN_USER ) );
829 bool bNoLockAccess = false;
830 try
831 {
833 LockFileEntry aData = aLockFile.GetLockData();
834 if ( !aData[LockFileComponent::OOOUSERNAME].isEmpty() )
835 {
836 aUserName = aData[LockFileComponent::OOOUSERNAME];
837 }
838 else if ( !aData[LockFileComponent::SYSUSERNAME].isEmpty() )
839 {
840 aUserName = aData[LockFileComponent::SYSUSERNAME];
841 }
842 }
843 catch ( uno::Exception& )
844 {
845 bNoLockAccess = true;
846 }
847
848 if ( bNoLockAccess )
849 {
850 // TODO/LATER: in future an error regarding impossibility to open file for writing could be shown
852 }
853 else
854 {
855 OUString aMessage( ScResId( STR_FILE_LOCKED_SAVE_LATER ) );
856 aMessage = aMessage.replaceFirst( "%1", aUserName );
857
858 std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(GetActiveDialogParent(),
859 VclMessageType::Warning, VclButtonsType::NONE,
860 aMessage));
861 xWarn->add_button(GetStandardText(StandardButtonType::Retry), RET_RETRY);
862 xWarn->add_button(GetStandardText(StandardButtonType::Cancel), RET_CANCEL);
863 xWarn->set_default_response(RET_RETRY);
864 if (xWarn->run() == RET_RETRY)
865 {
866 bRetry = true;
867 }
868 }
869 }
870 else
871 {
872 // merge changes from shared file into temp file
873 bool bSaveToShared = false;
874 if ( pSharedDocShell )
875 {
876 bSaveToShared = MergeSharedDocument( pSharedDocShell );
877 }
878
879 // close shared file
880 xCloseable->close( true );
881
882 // TODO: keep file lock on shared file
883
884 // store to shared file
885 if ( bSaveToShared )
886 {
887 bool bChangedViewSettings = false;
888 ScChangeViewSettings* pChangeViewSet = m_pDocument->GetChangeViewSettings();
889 if ( pChangeViewSet && pChangeViewSet->ShowChanges() )
890 {
891 pChangeViewSet->SetShowChanges( false );
892 pChangeViewSet->SetShowAccepted( false );
893 m_pDocument->SetChangeViewSettings( *pChangeViewSet );
894 bChangedViewSettings = true;
895 }
896
897 uno::Reference< frame::XStorable > xStor( GetModel(), uno::UNO_QUERY_THROW );
898 // TODO/LATER: More entries from the MediaDescriptor might be interesting for the merge
899 uno::Sequence< beans::PropertyValue > aValues{
901 "FilterName",
902 GetMedium()->GetFilter()->GetFilterName())
903 };
904
905 const SfxStringItem* pPasswordItem = SfxItemSet::GetItem<SfxStringItem>(GetMedium()->GetItemSet(), SID_PASSWORD, false);
906 if ( pPasswordItem && !pPasswordItem->GetValue().isEmpty() )
907 {
908 aValues.realloc( 2 );
909 auto pValues = aValues.getArray();
910 pValues[1].Name = "Password";
911 pValues[1].Value <<= pPasswordItem->GetValue();
912 }
913
914 SC_MOD()->SetInSharedDocSaving( true );
915 xStor->storeToURL( GetSharedFileURL(), aValues );
916 SC_MOD()->SetInSharedDocSaving( false );
917
918 if ( bChangedViewSettings )
919 {
920 pChangeViewSet->SetShowChanges( true );
921 pChangeViewSet->SetShowAccepted( true );
922 m_pDocument->SetChangeViewSettings( *pChangeViewSet );
923 }
924 }
925
926 bSuccess = true;
928 }
929 }
930 else
931 {
932 xCloseable->close( true );
933
934 if ( bEntriesNotAccessible )
935 {
936 // TODO/LATER: in future an error regarding impossibility to write to share control file could be shown
938 }
939 else
940 {
941 std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(GetActiveDialogParent(),
942 VclMessageType::Warning, VclButtonsType::Ok,
943 ScResId(STR_DOC_NOLONGERSHARED)));
944 xWarn->run();
945
946 SfxBindings* pBindings = GetViewBindings();
947 if ( pBindings )
948 {
949 pBindings->ExecuteSynchron( SID_SAVEASDOC );
950 }
951 }
952 }
953 }
954 catch ( uno::Exception& )
955 {
956 TOOLS_WARN_EXCEPTION( "sc", "SfxEventHintId::SaveDoc" );
957 SC_MOD()->SetInSharedDocSaving( false );
958
959 try
960 {
961 uno::Reference< util::XCloseable > xClose( xModel, uno::UNO_QUERY_THROW );
962 xClose->close( true );
963 }
964 catch ( uno::Exception& )
965 {
966 }
967 }
968 }
969
970 if ( !bSuccess )
971 SetError(ERRCODE_IO_ABORT); // this error code will produce no error message, but will break the further saving process
972 }
973#endif
974
976 m_pSheetSaveData->SetInSupportedSave(true);
977 }
978 break;
979 case SfxEventHintId::SaveAsDoc:
980 {
981 if ( GetDocument().GetExternalRefManager()->containsUnsavedReferences() )
982 {
983 std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(GetActiveDialogParent(),
984 VclMessageType::Warning, VclButtonsType::YesNo,
985 ScResId(STR_UNSAVED_EXT_REF)));
986 if (RET_NO == xWarn->run())
987 {
988 SetError(ERRCODE_IO_ABORT); // this error code will produce no error message, but will break the further saving process
989 }
990 }
991 [[fallthrough]];
992 }
993 case SfxEventHintId::SaveToDoc:
994 // #i108978# If no event is sent before saving, there will also be no "...DONE" event,
995 // and SAVE/SAVEAS can't be distinguished from SAVETO. So stream copying is only enabled
996 // if there is a SAVE/SAVEAS/SAVETO event first.
998 m_pSheetSaveData->SetInSupportedSave(true);
999 break;
1000 case SfxEventHintId::SaveDocDone:
1001 case SfxEventHintId::SaveAsDocDone:
1002 {
1003 // new positions are used after "save" and "save as", but not "save to"
1004 UseSheetSaveEntries(); // use positions from saved file for next saving
1005 [[fallthrough]];
1006 }
1007 case SfxEventHintId::SaveToDocDone:
1008 // only reset the flag, don't use the new positions
1009 if (m_pSheetSaveData)
1010 m_pSheetSaveData->SetInSupportedSave(false);
1011 break;
1012 default:
1013 {
1014 }
1015 break;
1016 }
1017 }
1018 else if (rHint.GetId() == SfxHintId::TitleChanged) // Without parameter
1019 {
1020 m_pDocument->SetName( SfxShell::GetName() );
1021 // RegisterNewTargetNames doesn't exist any longer
1022 SfxGetpApp()->Broadcast(SfxHint( SfxHintId::ScDocNameChanged )); // Navigator
1023 }
1024 else if (rHint.GetId() == SfxHintId::Deinitializing)
1025 {
1026
1027#if HAVE_FEATURE_SCRIPTING
1028 uno::Reference<script::vba::XVBACompatibility> xVBACompat(GetBasicContainer(), uno::UNO_QUERY);
1029 if (m_xVBAListener.is() && xVBACompat.is())
1030 {
1031 xVBACompat->removeVBAScriptListener(m_xVBAListener);
1032 }
1033#endif
1034
1035 if (m_pDocument->IsClipboardSource())
1036 {
1037 // Notes copied to the clipboard have a raw SdrCaptionObj pointer
1038 // copied from this document, forget it as it references this
1039 // document's drawing layer pages and what not, which otherwise when
1040 // pasting to another document after this document was destructed would
1041 // attempt to access non-existing data. Preserve the text data though.
1042 ScDocument* pClipDoc = ScModule::GetClipDoc();
1043 if (pClipDoc)
1044 pClipDoc->ClosingClipboardSource();
1045 }
1046 }
1047
1048 const SfxEventHint* pSfxEventHint = dynamic_cast<const SfxEventHint*>(&rHint);
1049 if (!pSfxEventHint)
1050 return;
1051
1052 switch( pSfxEventHint->GetEventId() )
1053 {
1054 case SfxEventHintId::CreateDoc:
1055 {
1056 uno::Any aWorkbook;
1057 aWorkbook <<= mxAutomationWorkbookObject;
1058 uno::Sequence< uno::Any > aArgs{ aWorkbook };
1059 SC_MOD()->CallAutomationApplicationEventSinks( "NewWorkbook", aArgs );
1060 }
1061 break;
1062 case SfxEventHintId::OpenDoc:
1063 {
1064 uno::Any aWorkbook;
1065 aWorkbook <<= mxAutomationWorkbookObject;
1066 uno::Sequence< uno::Any > aArgs{ aWorkbook };
1067 SC_MOD()->CallAutomationApplicationEventSinks( "WorkbookOpen", aArgs );
1068 }
1069 break;
1070 default:
1071 break;
1072 }
1073}
1074
1075// Load contents for organizer
1077{
1078 LoadMediumGuard aLoadGuard(m_pDocument.get());
1079 ScRefreshTimerProtector aProt( m_pDocument->GetRefreshTimerControlAddress() );
1080
1082
1083 bool bRet = false;
1084
1085 SetInitialLinkUpdate(&rMedium);
1086
1087 // until loading/saving only the styles in XML is implemented,
1088 // load the whole file
1089 bRet = LoadXML( &rMedium, nullptr );
1090 InitItems();
1091
1092 SfxObjectShell::LoadFrom( rMedium );
1093
1094 return bRet;
1095}
1096
1097static void lcl_parseHtmlFilterOption(const OUString& rOption, LanguageType& rLang, bool& rDateConvert)
1098{
1099 OUStringBuffer aBuf;
1100 std::vector< OUString > aTokens;
1101 sal_Int32 n = rOption.getLength();
1102 const sal_Unicode* p = rOption.getStr();
1103 for (sal_Int32 i = 0; i < n; ++i)
1104 {
1105 const sal_Unicode c = p[i];
1106 if (c == ' ')
1107 {
1108 if (!aBuf.isEmpty())
1109 aTokens.push_back( aBuf.makeStringAndClear() );
1110 }
1111 else
1112 aBuf.append(c);
1113 }
1114
1115 if (!aBuf.isEmpty())
1116 aTokens.push_back( aBuf.makeStringAndClear() );
1117
1118 rLang = LanguageType( 0 );
1119 rDateConvert = false;
1120
1121 if (!aTokens.empty())
1122 rLang = static_cast<LanguageType>(aTokens[0].toInt32());
1123 if (aTokens.size() > 1)
1124 rDateConvert = static_cast<bool>(aTokens[1].toInt32());
1125}
1126
1128{
1129 LoadMediumGuard aLoadGuard(m_pDocument.get());
1130
1131 bool bRet = false; // sal_False means user quit!
1132 // On error: Set error at stream
1133
1134 ScRefreshTimerProtector aProt( m_pDocument->GetRefreshTimerControlAddress() );
1135
1136 GetUndoManager()->Clear();
1137
1138 // Set optimal col width after import?
1139 bool bSetColWidths = false;
1140 bool bSetSimpleTextColWidths = false;
1141 std::map<SCCOL, ScColWidthParam> aColWidthParam;
1142 ScRange aColWidthRange;
1143 // Set optimal row height after import?
1144 bool bSetRowHeights = false;
1145
1146 vector<ScDocRowHeightUpdater::TabRanges> aRecalcRowRangesArray;
1147
1148 // All filters need the complete file in one piece (not asynchronously)
1149 // So make sure that we transfer the whole file with CreateFileStream
1150 rMedium.GetPhysicalName();
1151
1152 SetInitialLinkUpdate(&rMedium);
1153
1154 std::shared_ptr<const SfxFilter> pFilter = rMedium.GetFilter();
1155 if (pFilter)
1156 {
1157 OUString aFltName = pFilter->GetFilterName();
1158
1159 bool bCalc3 = aFltName == "StarCalc 3.0";
1160 bool bCalc4 = aFltName == "StarCalc 4.0";
1161 if (!bCalc3 && !bCalc4)
1162 m_pDocument->SetInsertingFromOtherDoc( true );
1163
1164 if (aFltName == pFilterXML)
1165 bRet = LoadXML( &rMedium, nullptr );
1166 else if (aFltName == pFilterLotus)
1167 {
1168 OUString sItStr;
1169 SfxItemSet* pSet = rMedium.GetItemSet();
1170 const SfxStringItem* pOptionsItem;
1171 if ( pSet &&
1172 (pOptionsItem = pSet->GetItemIfSet( SID_FILE_FILTEROPTIONS, true )) )
1173 {
1174 sItStr = pOptionsItem->GetValue();
1175 }
1176
1177 if (sItStr.isEmpty())
1178 {
1179 // default for lotus import (from API without options):
1180 // IBM_437 encoding
1181 sItStr = ScGlobal::GetCharsetString( RTL_TEXTENCODING_IBM_437 );
1182 }
1183
1186 if (eError != ERRCODE_NONE)
1187 {
1188 if (!GetError())
1189 SetError(eError);
1190
1191 if( eError.IsWarning() )
1192 bRet = true;
1193 }
1194 else
1195 bRet = true;
1196 bSetColWidths = true;
1197 bSetRowHeights = true;
1198 }
1199 else if ( aFltName == pFilterExcel4 || aFltName == pFilterExcel5 ||
1200 aFltName == pFilterExcel95 || aFltName == pFilterExcel97 ||
1201 aFltName == pFilterEx4Temp || aFltName == pFilterEx5Temp ||
1202 aFltName == pFilterEx95Temp || aFltName == pFilterEx97Temp )
1203 {
1204 EXCIMPFORMAT eFormat = EIF_AUTO;
1205 if ( aFltName == pFilterExcel4 || aFltName == pFilterEx4Temp )
1206 eFormat = EIF_BIFF_LE4;
1207 else if ( aFltName == pFilterExcel5 || aFltName == pFilterExcel95 ||
1208 aFltName == pFilterEx5Temp || aFltName == pFilterEx95Temp )
1209 eFormat = EIF_BIFF5;
1210 else if ( aFltName == pFilterExcel97 || aFltName == pFilterEx97Temp )
1211 eFormat = EIF_BIFF8;
1212
1213 MakeDrawLayer();
1214 CalcOutputFactor(); // prepare update of row height
1215 ErrCode eError = ScFormatFilter::Get().ScImportExcel( rMedium, m_pDocument.get(), eFormat );
1216 m_pDocument->UpdateFontCharSet();
1217 if ( m_pDocument->IsChartListenerCollectionNeedsUpdate() )
1218 m_pDocument->UpdateChartListenerCollection();
1219
1220 // all graphics objects must have names
1221 m_pDocument->EnsureGraphicNames();
1222
1223 if (eError != ERRCODE_NONE)
1224 {
1225 if (!GetError())
1226 SetError(eError);
1227 if( eError.IsWarning() )
1228 bRet = true;
1229 }
1230 else
1231 bRet = true;
1232 }
1233 else if (aFltName == "Gnumeric Spreadsheet")
1234 {
1236 if (!pOrcus)
1237 return false;
1238
1239 bRet = pOrcus->importGnumeric(*m_pDocument, rMedium);
1240 }
1241 else if (aFltName == "MS Excel 2003 XML Orcus")
1242 {
1244 if (!pOrcus)
1245 return false;
1246
1247 bRet = pOrcus->importExcel2003XML(*m_pDocument, rMedium);
1248 }
1249 else if (aFltName == SC_TEXT_CSV_FILTER_NAME)
1250 {
1251 SfxItemSet* pSet = rMedium.GetItemSet();
1252 const SfxStringItem* pOptionsItem;
1253 ScAsciiOptions aOptions;
1254 bool bOptInit = false;
1255
1256 if ( pSet &&
1257 (pOptionsItem = pSet->GetItemIfSet( SID_FILE_FILTEROPTIONS )) )
1258 {
1259 aOptions.ReadFromString( pOptionsItem->GetValue() );
1260 bOptInit = true;
1261 }
1262
1263 if ( !bOptInit )
1264 {
1265 // default for ascii import (from API without options):
1266 // ISO8859-1/MS_1252 encoding, comma, double quotes
1267
1268 aOptions.SetCharSet( RTL_TEXTENCODING_MS_1252 );
1269 aOptions.SetFieldSeps( OUString(',') );
1270 aOptions.SetTextSep( '"' );
1271 }
1272
1273 ErrCode eError = ERRCODE_NONE;
1274 bool bOverflowRow, bOverflowCol, bOverflowCell;
1275 bOverflowRow = bOverflowCol = bOverflowCell = false;
1276
1277 if( ! rMedium.IsStorage() )
1278 {
1279 ScImportExport aImpEx( *m_pDocument );
1280 aImpEx.SetExtOptions( aOptions );
1281
1282 SvStream* pInStream = rMedium.GetInStream();
1283 if (pInStream)
1284 {
1285 pInStream->SetStreamCharSet( aOptions.GetCharSet() );
1286 pInStream->Seek( 0 );
1287 bRet = aImpEx.ImportStream( *pInStream, rMedium.GetBaseURL(), SotClipboardFormatId::STRING );
1288 eError = bRet ? ERRCODE_NONE : SCERR_IMPORT_CONNECT;
1289 m_pDocument->StartAllListeners();
1291 m_pDocument->SetAllFormulasDirty(aCxt);
1292
1295 // for mobile case, we use a copy of the original document and give it a temporary name before editing
1296 // Therefore, the sheet name becomes ugly, long and nonsensical.
1297 if (!bIsMobile)
1298 // The same resulting name has to be handled in
1299 // ScExternalRefCache::initializeDoc() and related, hence
1300 // pass 'true' for RenameTab()'s bExternalDocument for a
1301 // composed name so ValidTabName() will not be checked,
1302 // which could veto the rename in case it contained
1303 // characters that Excel does not handle. If we wanted to
1304 // change that then it needed to be handled in all
1305 // corresponding places of the external references
1306 // manager/cache. Likely then we'd also need a method to
1307 // compose a name excluding such characters.
1308 m_pDocument->RenameTab( 0, INetURLObject( rMedium.GetName()).GetBase(), true/*bExternalDocument*/);
1309
1310 bOverflowRow = aImpEx.IsOverflowRow();
1311 bOverflowCol = aImpEx.IsOverflowCol();
1312 bOverflowCell = aImpEx.IsOverflowCell();
1313 }
1314 else
1315 {
1316 OSL_FAIL( "No Stream" );
1317 }
1318 }
1319
1320 if (eError != ERRCODE_NONE)
1321 {
1322 if (!GetError())
1323 SetError(eError);
1324 if( eError.IsWarning() )
1325 bRet = true;
1326 }
1327 else if (!GetError() && (bOverflowRow || bOverflowCol || bOverflowCell))
1328 {
1329 // precedence: row, column, cell
1330 ErrCode nWarn = (bOverflowRow ? SCWARN_IMPORT_ROW_OVERFLOW :
1331 (bOverflowCol ? SCWARN_IMPORT_COLUMN_OVERFLOW :
1333 SetError(nWarn);
1334 }
1335 bSetColWidths = true;
1336 bSetSimpleTextColWidths = true;
1337 }
1338 else if (aFltName == pFilterDBase)
1339 {
1340 OUString sItStr;
1341 SfxItemSet* pSet = rMedium.GetItemSet();
1342 const SfxStringItem* pOptionsItem;
1343 if ( pSet &&
1344 (pOptionsItem = pSet->GetItemIfSet( SID_FILE_FILTEROPTIONS )) )
1345 {
1346 sItStr = pOptionsItem->GetValue();
1347 }
1348
1349 if (sItStr.isEmpty())
1350 {
1351 // default for dBase import (from API without options):
1352 // IBM_850 encoding
1353
1354 sItStr = ScGlobal::GetCharsetString( RTL_TEXTENCODING_IBM_850 );
1355 }
1356
1357 ScDocRowHeightUpdater::TabRanges aRecalcRanges(0, m_pDocument->MaxRow());
1358 ErrCode eError = DBaseImport( rMedium.GetPhysicalName(),
1359 ScGlobal::GetCharsetValue(sItStr), aColWidthParam, aRecalcRanges.maRanges );
1360 aRecalcRowRangesArray.push_back(aRecalcRanges);
1361
1362 if (eError != ERRCODE_NONE)
1363 {
1364 if (!GetError())
1365 SetError(eError);
1366 if( eError.IsWarning() )
1367 bRet = true;
1368 }
1369 else
1370 bRet = true;
1371
1372 aColWidthRange.aStart.SetRow( 1 ); // Except for the column header
1373 bSetColWidths = true;
1374 bSetSimpleTextColWidths = true;
1375 }
1376 else if (aFltName == pFilterDif)
1377 {
1378 SvStream* pStream = rMedium.GetInStream();
1379 if (pStream)
1380 {
1381 ErrCode eError;
1382 OUString sItStr;
1383 SfxItemSet* pSet = rMedium.GetItemSet();
1384 const SfxStringItem* pOptionsItem;
1385 if ( pSet &&
1386 (pOptionsItem = pSet->GetItemIfSet( SID_FILE_FILTEROPTIONS )) )
1387 {
1388 sItStr = pOptionsItem->GetValue();
1389 }
1390
1391 if (sItStr.isEmpty())
1392 {
1393 // default for DIF import (from API without options):
1394 // ISO8859-1/MS_1252 encoding
1395
1396 sItStr = ScGlobal::GetCharsetString( RTL_TEXTENCODING_MS_1252 );
1397 }
1398
1399 eError = ScFormatFilter::Get().ScImportDif( *pStream, m_pDocument.get(), ScAddress(0,0,0),
1401 if (eError != ERRCODE_NONE)
1402 {
1403 if (!GetError())
1404 SetError(eError);
1405
1406 if( eError.IsWarning() )
1407 bRet = true;
1408 }
1409 else
1410 bRet = true;
1411 }
1412 bSetColWidths = true;
1413 bSetSimpleTextColWidths = true;
1414 bSetRowHeights = true;
1415 }
1416 else if (aFltName == pFilterSylk)
1417 {
1419 bool bOverflowRow, bOverflowCol, bOverflowCell;
1420 bOverflowRow = bOverflowCol = bOverflowCell = false;
1421 if( !rMedium.IsStorage() )
1422 {
1423 ScImportExport aImpEx( *m_pDocument );
1424
1425 SvStream* pInStream = rMedium.GetInStream();
1426 if (pInStream)
1427 {
1428 pInStream->Seek( 0 );
1429 bRet = aImpEx.ImportStream( *pInStream, rMedium.GetBaseURL(), SotClipboardFormatId::SYLK );
1430 eError = bRet ? ERRCODE_NONE : SCERR_IMPORT_UNKNOWN;
1431 m_pDocument->StartAllListeners();
1433 m_pDocument->SetAllFormulasDirty(aCxt);
1434
1435 bOverflowRow = aImpEx.IsOverflowRow();
1436 bOverflowCol = aImpEx.IsOverflowCol();
1437 bOverflowCell = aImpEx.IsOverflowCell();
1438 }
1439 else
1440 {
1441 OSL_FAIL( "No Stream" );
1442 }
1443 }
1444
1445 if (eError != ERRCODE_NONE)
1446 {
1447 if (!GetError())
1448 SetError(eError);
1449 if( eError.IsWarning() )
1450 bRet = true;
1451 }
1452 else if (!GetError() && (bOverflowRow || bOverflowCol || bOverflowCell))
1453 {
1454 // precedence: row, column, cell
1455 ErrCode nWarn = (bOverflowRow ? SCWARN_IMPORT_ROW_OVERFLOW :
1456 (bOverflowCol ? SCWARN_IMPORT_COLUMN_OVERFLOW :
1458 SetError(nWarn);
1459 }
1460 bSetColWidths = true;
1461 bSetSimpleTextColWidths = true;
1462 bSetRowHeights = true;
1463 }
1464 else if (aFltName == pFilterQPro6)
1465 {
1467 if (eError != ERRCODE_NONE)
1468 {
1469 if (!GetError())
1470 SetError(eError);
1471 if( eError.IsWarning() )
1472 bRet = true;
1473 }
1474 else
1475 bRet = true;
1476 // TODO: Filter should set column widths. Not doing it here, it may
1477 // result in very narrow or wide columns, depending on content.
1478 // Setting row heights makes cells with font size attribution or
1479 // wrapping enabled look nicer...
1480 bSetRowHeights = true;
1481 }
1482 else if (aFltName == pFilterRtf)
1483 {
1485 if( !rMedium.IsStorage() )
1486 {
1487 SvStream* pInStream = rMedium.GetInStream();
1488 if (pInStream)
1489 {
1490 pInStream->Seek( 0 );
1491 ScRange aRange;
1492 eError = ScFormatFilter::Get().ScImportRTF( *pInStream, rMedium.GetBaseURL(), m_pDocument.get(), aRange );
1493 if (eError != ERRCODE_NONE)
1494 {
1495 if (!GetError())
1496 SetError(eError);
1497
1498 if( eError.IsWarning() )
1499 bRet = true;
1500 }
1501 else
1502 bRet = true;
1503 m_pDocument->StartAllListeners();
1505 m_pDocument->SetAllFormulasDirty(aCxt);
1506 bSetColWidths = true;
1507 bSetRowHeights = true;
1508 }
1509 else
1510 {
1511 OSL_FAIL( "No Stream" );
1512 }
1513 }
1514
1515 if (eError != ERRCODE_NONE)
1516 {
1517 if (!GetError())
1518 SetError(eError);
1519 if( eError.IsWarning() )
1520 bRet = true;
1521 }
1522 }
1523 else if (aFltName == pFilterHtml || aFltName == pFilterHtmlWebQ)
1524 {
1526 bool bWebQuery = aFltName == pFilterHtmlWebQ;
1527 if( !rMedium.IsStorage() )
1528 {
1529 SvStream* pInStream = rMedium.GetInStream();
1530 if (pInStream)
1531 {
1533 bool bDateConvert = false;
1534 SfxItemSet* pSet = rMedium.GetItemSet();
1535 const SfxStringItem* pOptionsItem;
1536 if ( pSet &&
1537 (pOptionsItem = pSet->GetItemIfSet( SID_FILE_FILTEROPTIONS )) )
1538 {
1539 OUString aFilterOption = pOptionsItem->GetValue();
1540 lcl_parseHtmlFilterOption(aFilterOption, eLang, bDateConvert);
1541 }
1542
1543 pInStream->Seek( 0 );
1544 ScRange aRange;
1545 // HTML does its own ColWidth/RowHeight
1548 eError = ScFormatFilter::Get().ScImportHTML( *pInStream, rMedium.GetBaseURL(), m_pDocument.get(), aRange,
1549 GetOutputFactor(), !bWebQuery, &aNumFormatter, bDateConvert );
1550 if (eError != ERRCODE_NONE)
1551 {
1552 if (!GetError())
1553 SetError(eError);
1554
1555 if( eError.IsWarning() )
1556 bRet = true;
1557 }
1558 else
1559 bRet = true;
1560 m_pDocument->StartAllListeners();
1561
1563 m_pDocument->SetAllFormulasDirty(aCxt);
1564 }
1565 else
1566 {
1567 OSL_FAIL( "No Stream" );
1568 }
1569 }
1570
1571 if (eError != ERRCODE_NONE)
1572 {
1573 if (!GetError())
1574 SetError(eError);
1575 if( eError.IsWarning() )
1576 bRet = true;
1577 }
1578 }
1579 else
1580 {
1581 if (!GetError())
1582 {
1583 SAL_WARN("sc.filter", "No match for filter '" << aFltName << "' in ConvertFrom");
1585 }
1586 }
1587
1588 if (!bCalc3)
1589 m_pDocument->SetInsertingFromOtherDoc( false );
1590 }
1591 else
1592 {
1593 OSL_FAIL("No Filter in ConvertFrom");
1594 }
1595
1596 InitItems();
1598 if ( bRet && (bSetColWidths || bSetRowHeights) )
1599 { // Adjust column width/row height; base 100% zoom
1600 Fraction aZoom( 1, 1 );
1601 double nPPTX = ScGlobal::nScreenPPTX * static_cast<double>(aZoom) / GetOutputFactor(); // Factor is printer display ratio
1602 double nPPTY = ScGlobal::nScreenPPTY * static_cast<double>(aZoom);
1604 // all sheets (for Excel import)
1605 SCTAB nTabCount = m_pDocument->GetTableCount();
1606 for (SCTAB nTab=0; nTab<nTabCount; nTab++)
1607 {
1608 SCCOL nEndCol;
1609 SCROW nEndRow;
1610 m_pDocument->GetCellArea( nTab, nEndCol, nEndRow );
1611 aColWidthRange.aEnd.SetCol( nEndCol );
1612 aColWidthRange.aEnd.SetRow( nEndRow );
1613 ScMarkData aMark(m_pDocument->GetSheetLimits());
1614 aMark.SetMarkArea( aColWidthRange );
1615 aMark.MarkToMulti();
1616
1617 // Order is important: First width, then height
1618 if ( bSetColWidths )
1619 {
1620 for ( SCCOL nCol=0; nCol <= nEndCol; nCol++ )
1621 {
1622 if (!bSetSimpleTextColWidths)
1623 aColWidthParam[nCol].mbSimpleText = false;
1624
1625 sal_uInt16 nWidth = m_pDocument->GetOptimalColWidth(
1626 nCol, nTab, pVirtDev, nPPTX, nPPTY, aZoom, aZoom, false, &aMark,
1627 &aColWidthParam[nCol] );
1628 m_pDocument->SetColWidth( nCol, nTab,
1629 nWidth + static_cast<sal_uInt16>(ScGlobal::nLastColWidthExtra) );
1630 }
1631 }
1632 }
1633
1634 if (bSetRowHeights)
1635 {
1636 // Update all rows in all tables.
1637 ScSizeDeviceProvider aProv(this);
1638 ScDocRowHeightUpdater aUpdater(*m_pDocument, aProv.GetDevice(), aProv.GetPPTX(), aProv.GetPPTY(), nullptr);
1639 aUpdater.update();
1640 }
1641 else if (!aRecalcRowRangesArray.empty())
1642 {
1643 // Update only specified row ranges for better performance.
1644 ScSizeDeviceProvider aProv(this);
1645 ScDocRowHeightUpdater aUpdater(*m_pDocument, aProv.GetDevice(), aProv.GetPPTX(), aProv.GetPPTY(), &aRecalcRowRangesArray);
1646 aUpdater.update();
1647 }
1648 }
1650
1651 // invalidate eventually temporary table areas
1652 if ( bRet )
1653 m_pDocument->InvalidateTableArea();
1654
1655 m_bIsEmpty = false;
1656
1657 return bRet;
1658}
1659
1661{
1662 std::shared_ptr<const SfxFilter> pFilter = rMed.GetFilter();
1663 if (!pFilter)
1664 return false;
1665
1666 if (pFilter->GetProviderName() == "orcus")
1667 {
1669 if (!pOrcus)
1670 return false;
1671
1672 const OUString& rFilterName = pFilter->GetName();
1673 if (rFilterName == "gnumeric")
1674 {
1675 if (!pOrcus->importGnumeric(*m_pDocument, rMed))
1676 return false;
1677 }
1678 else if (rFilterName == "csv")
1679 {
1680 if (!pOrcus->importCSV(*m_pDocument, rMed))
1681 return false;
1682 }
1683 else if (rFilterName == "xlsx")
1684 {
1685 if (!pOrcus->importXLSX(*m_pDocument, rMed))
1686 return false;
1687 }
1688 else if (rFilterName == "ods")
1689 {
1690 if (!pOrcus->importODS(*m_pDocument, rMed))
1691 return false;
1692 }
1693
1695 return true;
1696 }
1697
1698 return false;
1699}
1700
1702 : mrDocShell( rDocShell)
1703{
1704 // DoEnterHandler not here (because of AutoSave), is in ExecuteSave.
1705
1706 ScChartListenerCollection* pCharts = mrDocShell.m_pDocument->GetChartListenerCollection();
1707 if (pCharts)
1708 pCharts->UpdateDirtyCharts(); // Charts to be updated.
1709 mrDocShell.m_pDocument->StopTemporaryChartLock();
1711 mrDocShell.m_pAutoStyleList->ExecuteAllNow(); // Execute template timeouts now.
1712 if (mrDocShell.m_pDocument->HasExternalRefManager())
1713 {
1714 ScExternalRefManager* pRefMgr = mrDocShell.m_pDocument->GetExternalRefManager();
1715 if (pRefMgr && pRefMgr->hasExternalData())
1716 {
1717 pRefMgr->setAllCacheTableReferencedStati( false);
1718 mrDocShell.m_pDocument->MarkUsedExternalReferences(); // Mark tables of external references to be written.
1719 }
1720 }
1721 if (mrDocShell.GetCreateMode()== SfxObjectCreateMode::STANDARD)
1722 mrDocShell.SfxObjectShell::SetVisArea( tools::Rectangle() ); // "Normally" worked on => no VisArea.
1723}
1724
1726{
1727 if (mrDocShell.m_pDocument->HasExternalRefManager())
1728 {
1729 ScExternalRefManager* pRefMgr = mrDocShell.m_pDocument->GetExternalRefManager();
1730 if (pRefMgr && pRefMgr->hasExternalData())
1731 {
1732 // Prevent accidental data loss due to lack of knowledge.
1733 pRefMgr->setAllCacheTableReferencedStati( true);
1734 }
1735 }
1736}
1737
1739{
1740 ScRefreshTimerProtector aProt( m_pDocument->GetRefreshTimerControlAddress() );
1741
1742 PrepareSaveGuard aPrepareGuard( *this);
1743
1744 if (const auto pFrame1 = SfxViewFrame::GetFirst(this))
1745 {
1746 if (auto pSysWin = pFrame1->GetWindow().GetSystemWindow())
1747 {
1748 pSysWin->SetAccessibleName(OUString());
1749 }
1750 }
1751 // wait cursor is handled with progress bar
1752 bool bRet = SfxObjectShell::Save();
1753 if( bRet )
1754 bRet = SaveXML( GetMedium(), nullptr );
1755 return bRet;
1756}
1757
1758namespace {
1759
1763void popFileName(OUString& rPath)
1764{
1765 if (!rPath.isEmpty())
1766 {
1767 INetURLObject aURLObj(rPath);
1768 aURLObj.removeSegment();
1769 rPath = aURLObj.GetMainURL(INetURLObject::DecodeMechanism::NONE);
1770 }
1771}
1772
1773}
1774
1776{
1777 // Commit any cell changes before saving.
1778 SC_MOD()->InputEnterHandler();
1779}
1780
1782{
1783 OUString aCurPath; // empty for new document that hasn't been saved.
1784 const SfxMedium* pCurMedium = GetMedium();
1785 if (pCurMedium)
1786 {
1787 aCurPath = pCurMedium->GetName();
1788 popFileName(aCurPath);
1789 }
1790
1791 if (!aCurPath.isEmpty())
1792 {
1793 // current document has a path -> not a brand-new document.
1794 OUString aNewPath = rMedium.GetName();
1795 popFileName(aNewPath);
1796 OUString aRel = URIHelper::simpleNormalizedMakeRelative(aCurPath, aNewPath);
1797 if (!aRel.isEmpty())
1798 {
1799 // Directory path will change before and after the save.
1800 m_pDocument->InvalidateStreamOnSave();
1801 }
1802 }
1803
1804 ScTabViewShell* pViewShell = GetBestViewShell();
1806 if (bNeedsRehash)
1807 // legacy xls hash double-hashed by SHA1 is also supported.
1809 if (bNeedsRehash)
1810 { // SHA256 explicitly supported in ODF 1.2, implicitly in ODF 1.1
1812 }
1813
1814 // skip saving recovery file instead of showing re-type password dialog window
1815 if ( bNeedsRehash && rMedium.GetFilter()->GetFilterName() == "calc8" &&
1816 // it seems, utl::MediaDescriptor::PROP_AUTOSAVEEVENT is true at Save As, too,
1817 // so check the backup path
1818 rMedium.GetName().startsWith( SvtPathOptions().GetBackupPath() ) )
1819 {
1820 SAL_WARN("sc.filter", "Should re-type password for own format, won't export recovery file");
1822 return false;
1823 }
1824
1825 if (pViewShell && bNeedsRehash)
1826 {
1827 if (!pViewShell->ExecuteRetypePassDlg(PASSHASH_SHA1))
1828 // password re-type cancelled. Don't save the document.
1829 return false;
1830 }
1831
1832 ScRefreshTimerProtector aProt( m_pDocument->GetRefreshTimerControlAddress() );
1833
1834 PrepareSaveGuard aPrepareGuard( *this);
1835
1836 // wait cursor is handled with progress bar
1837 bool bRet = SfxObjectShell::SaveAs( rMedium );
1838 if (bRet)
1839 bRet = SaveXML( &rMedium, nullptr );
1840
1841 return bRet;
1842}
1843
1844namespace {
1845
1846// Xcl-like column width measured in characters of standard font.
1847sal_Int32 lcl_ScDocShell_GetColWidthInChars( sal_uInt16 nWidth )
1848{
1849 double f = nWidth;
1850 f *= 1328.0 / 25.0;
1851 f += 90.0;
1852 f *= 1.0 / 23.0;
1853 f /= 256.0;
1854
1855 return sal_Int32( f );
1856}
1857
1858void lcl_ScDocShell_GetFixedWidthString( OUString& rStr, const ScDocument& rDoc,
1859 SCTAB nTab, SCCOL nCol, bool bValue, SvxCellHorJustify eHorJust )
1860{
1861 OUString aString = rStr;
1862 sal_Int32 nLen = lcl_ScDocShell_GetColWidthInChars(
1863 rDoc.GetColWidth( nCol, nTab ) );
1864 //If the text won't fit in the column
1865 if ( nLen < aString.getLength() )
1866 {
1867 OUStringBuffer aReplacement;
1868 if (bValue)
1869 aReplacement.append("###");
1870 else
1871 aReplacement.append(aString);
1872 //truncate to the number of characters that should fit, even in the
1873 //bValue case nLen might be < len ###
1874 aString = comphelper::string::truncateToLength(aReplacement, nLen).makeStringAndClear();
1875 }
1876 if ( nLen > aString.getLength() )
1877 {
1878 if ( bValue && eHorJust == SvxCellHorJustify::Standard )
1879 eHorJust = SvxCellHorJustify::Right;
1880 OUStringBuffer aTmp(nLen);
1881 switch ( eHorJust )
1882 {
1883 case SvxCellHorJustify::Right:
1884 comphelper::string::padToLength( aTmp, nLen - aString.getLength(), ' ' );
1885 aString = aTmp.append(aString);
1886 break;
1887 case SvxCellHorJustify::Center:
1888 comphelper::string::padToLength( aTmp, (nLen - aString.getLength()) / 2, ' ' );
1889 [[fallthrough]];
1890 default:
1891 aTmp.append(aString);
1892 comphelper::string::padToLength( aTmp, nLen, ' ' );
1893 }
1894 aString = aTmp.makeStringAndClear();
1895 }
1896 rStr = aString;
1897}
1898
1899void lcl_ScDocShell_WriteEmptyFixedWidthString( SvStream& rStream,
1900 const ScDocument& rDoc, SCTAB nTab, SCCOL nCol )
1901{
1902 OUString aString;
1903 lcl_ScDocShell_GetFixedWidthString( aString, rDoc, nTab, nCol, false,
1904 SvxCellHorJustify::Standard );
1905 rStream.WriteUnicodeOrByteText( aString );
1906}
1907
1908template<typename StrT, typename SepCharT>
1909sal_Int32 getTextSepPos(
1910 const StrT& rStr, const ScImportOptions& rAsciiOpt, const SepCharT& rTextSep, const SepCharT& rFieldSep, bool& rNeedQuotes)
1911{
1912 // #i116636# quotes are needed if text delimiter (quote), field delimiter,
1913 // or LF or CR is in the cell text.
1914 sal_Int32 nPos = rStr.indexOf(rTextSep);
1915 rNeedQuotes = rAsciiOpt.bQuoteAllText || (nPos >= 0) ||
1916 (rStr.indexOf(rFieldSep) >= 0) ||
1917 (rStr.indexOf('\n') >= 0) ||
1918 (rStr.indexOf('\r') >= 0);
1919 return nPos;
1920}
1921
1922template<typename StrT, typename StrBufT>
1923void escapeTextSep(sal_Int32 nPos, const StrT& rStrDelim, StrT& rStr)
1924{
1925 while (nPos >= 0)
1926 {
1927 StrBufT aBuf(rStr);
1928 aBuf.insert(nPos, rStrDelim);
1929 rStr = aBuf.makeStringAndClear();
1930 nPos = rStr.indexOf(rStrDelim, nPos+1+rStrDelim.getLength());
1931 }
1932}
1933
1934}
1935
1936void ScDocShell::AsciiSave( SvStream& rStream, const ScImportOptions& rAsciiOpt, SCTAB nTab )
1937{
1938 sal_Unicode cDelim = rAsciiOpt.nFieldSepCode;
1939 sal_Unicode cStrDelim = rAsciiOpt.nTextSepCode;
1940 rtl_TextEncoding eCharSet = rAsciiOpt.eCharSet;
1941 bool bFixedWidth = rAsciiOpt.bFixedWidth;
1942 bool bSaveNumberAsSuch = rAsciiOpt.bSaveNumberAsSuch;
1943 bool bSaveAsShown = rAsciiOpt.bSaveAsShown;
1944 bool bShowFormulas = rAsciiOpt.bSaveFormulas;
1945
1946 rtl_TextEncoding eOldCharSet = rStream.GetStreamCharSet();
1947 rStream.SetStreamCharSet( eCharSet );
1948 SvStreamEndian nOldNumberFormatInt = rStream.GetEndian();
1949 OString aStrDelimEncoded; // only used if not Unicode
1950 OUString aStrDelimDecoded; // only used if context encoding
1951 OString aDelimEncoded;
1952 OUString aDelimDecoded;
1953 bool bContextOrNotAsciiEncoding;
1954 if ( eCharSet == RTL_TEXTENCODING_UNICODE )
1955 {
1956 rStream.StartWritingUnicodeText();
1957 bContextOrNotAsciiEncoding = false;
1958 }
1959 else
1960 {
1961 aStrDelimEncoded = OString(&cStrDelim, 1, eCharSet);
1962 aDelimEncoded = OString(&cDelim, 1, eCharSet);
1963 rtl_TextEncodingInfo aInfo;
1964 aInfo.StructSize = sizeof(aInfo);
1965 if ( rtl_getTextEncodingInfo( eCharSet, &aInfo ) )
1966 {
1967 bContextOrNotAsciiEncoding =
1968 (((aInfo.Flags & RTL_TEXTENCODING_INFO_CONTEXT) != 0) ||
1969 ((aInfo.Flags & RTL_TEXTENCODING_INFO_ASCII) == 0));
1970 if ( bContextOrNotAsciiEncoding )
1971 {
1972 aStrDelimDecoded = OStringToOUString(aStrDelimEncoded, eCharSet);
1973 aDelimDecoded = OStringToOUString(aDelimEncoded, eCharSet);
1974 }
1975 }
1976 else
1977 bContextOrNotAsciiEncoding = false;
1978 }
1979
1980 SCCOL nStartCol = 0;
1981 SCROW nStartRow = 0;
1982 SCCOL nEndCol;
1983 SCROW nEndRow;
1984 m_pDocument->GetCellArea( nTab, nEndCol, nEndRow );
1985
1986 ScProgress aProgress( this, ScResId( STR_SAVE_DOC ), nEndRow, true );
1987
1988 OUString aString;
1989
1990 bool bTabProtect = m_pDocument->IsTabProtected( nTab );
1991
1992 SCCOL nCol;
1993 SCROW nRow;
1994
1995 // Treat the top left cell separator "sep=" special.
1996 // Here nStartRow == 0 && nStartCol == 0
1997 if (!bFixedWidth && cDelim != 0)
1998 {
1999 // First row iterator.
2000 ScHorizontalCellIterator aIter( *m_pDocument, nTab, nStartCol, nStartRow, nEndCol, nStartRow);
2001 ScRefCellValue* pCell;
2002 // Must be first column and all following cells on this row must be
2003 // empty to fiddle with "sep=".
2004 if ((pCell = aIter.GetNext( nCol, nRow)) != nullptr && nCol == nStartCol && !aIter.GetNext( nCol, nRow))
2005 {
2006 if (pCell->getType() == CELLTYPE_STRING)
2007 {
2008 aString = pCell->getSharedString()->getString();
2009 if (aString.getLength() <= 5 && aString.startsWithIgnoreAsciiCase("sep="))
2010 {
2011 // Cell content is /^sep=.?$/ so write current separator.
2012 // Force the quote character to '"' regardless what is set
2013 // for export because that is the only one recognized on
2014 // import.
2015 aString = "sep=" + OUStringChar(cDelim);
2016 if (cStrDelim != 0)
2017 rStream.WriteUniOrByteChar( '"', eCharSet);
2018 if (eCharSet == RTL_TEXTENCODING_UNICODE)
2019 {
2020 write_uInt16s_FromOUString( rStream, aString);
2021 }
2022 else
2023 {
2024 OString aStrEnc = OUStringToOString( aString, eCharSet);
2025 // write byte encoded
2026 rStream.WriteBytes( aStrEnc.getStr(), aStrEnc.getLength());
2027 }
2028 if (cStrDelim != 0)
2029 rStream.WriteUniOrByteChar( '"', eCharSet);
2030 endlub( rStream );
2031 ++nStartRow;
2032 }
2033 }
2034 }
2035 }
2036
2037 SCCOL nNextCol = nStartCol;
2038 SCROW nNextRow = nStartRow;
2039 SCCOL nEmptyCol;
2040 SCROW nEmptyRow;
2041 SvNumberFormatter& rFormatter = *m_pDocument->GetFormatTable();
2042
2043 ScHorizontalCellIterator aIter( *m_pDocument, nTab, nStartCol, nStartRow,
2044 nEndCol, nEndRow );
2045 ScRefCellValue* pCell;
2046 while ( ( pCell = aIter.GetNext( nCol, nRow ) ) != nullptr )
2047 {
2048 bool bProgress = false; // only upon line change
2049 if ( nNextRow < nRow )
2050 { // empty rows or/and empty columns up to end of row
2051 bProgress = true;
2052 for ( nEmptyCol = nNextCol; nEmptyCol < nEndCol; nEmptyCol++ )
2053 { // remaining columns of last row
2054 if ( bFixedWidth )
2055 lcl_ScDocShell_WriteEmptyFixedWidthString( rStream,
2056 *m_pDocument, nTab, nEmptyCol );
2057 else if ( cDelim != 0 )
2058 rStream.WriteUniOrByteChar( cDelim );
2059 }
2060 endlub( rStream );
2061 nNextRow++;
2062 for ( nEmptyRow = nNextRow; nEmptyRow < nRow; nEmptyRow++ )
2063 { // completely empty rows
2064 for ( nEmptyCol = nStartCol; nEmptyCol < nEndCol; nEmptyCol++ )
2065 {
2066 if ( bFixedWidth )
2067 lcl_ScDocShell_WriteEmptyFixedWidthString( rStream,
2068 *m_pDocument, nTab, nEmptyCol );
2069 else if ( cDelim != 0 )
2070 rStream.WriteUniOrByteChar( cDelim );
2071 }
2072 endlub( rStream );
2073 }
2074 for ( nEmptyCol = nStartCol; nEmptyCol < nCol; nEmptyCol++ )
2075 { // empty columns at beginning of row
2076 if ( bFixedWidth )
2077 lcl_ScDocShell_WriteEmptyFixedWidthString( rStream,
2078 *m_pDocument, nTab, nEmptyCol );
2079 else if ( cDelim != 0 )
2080 rStream.WriteUniOrByteChar( cDelim );
2081 }
2082 nNextRow = nRow;
2083 }
2084 else if ( nNextCol < nCol )
2085 { // empty columns in same row
2086 for ( nEmptyCol = nNextCol; nEmptyCol < nCol; nEmptyCol++ )
2087 { // columns in between
2088 if ( bFixedWidth )
2089 lcl_ScDocShell_WriteEmptyFixedWidthString( rStream,
2090 *m_pDocument, nTab, nEmptyCol );
2091 else if ( cDelim != 0 )
2092 rStream.WriteUniOrByteChar( cDelim );
2093 }
2094 }
2095 if ( nCol == nEndCol )
2096 {
2097 bProgress = true;
2098 nNextCol = nStartCol;
2099 nNextRow = nRow + 1;
2100 }
2101 else
2102 nNextCol = nCol + 1;
2103
2104 CellType eType = pCell->getType();
2105 ScAddress aPos(nCol, nRow, nTab);
2106 if ( bTabProtect )
2107 {
2108 const ScProtectionAttr* pProtAttr =
2109 m_pDocument->GetAttr( nCol, nRow, nTab, ATTR_PROTECTION );
2110 if ( pProtAttr->GetHideCell() ||
2111 ( eType == CELLTYPE_FORMULA && bShowFormulas &&
2112 pProtAttr->GetHideFormula() ) )
2113 eType = CELLTYPE_NONE; // hide
2114 }
2115 bool bForceQuotes = false;
2116 bool bString;
2117 switch ( eType )
2118 {
2119 case CELLTYPE_NONE:
2120 aString.clear();
2121 bString = false;
2122 break;
2123 case CELLTYPE_FORMULA :
2124 {
2125 FormulaError nErrCode;
2126 if ( bShowFormulas )
2127 {
2128 aString = pCell->getFormula()->GetFormula();
2129 bString = true;
2130 }
2131 else if ((nErrCode = pCell->getFormula()->GetErrCode()) != FormulaError::NONE)
2132 {
2133 aString = ScGlobal::GetErrorString( nErrCode );
2134 bString = true;
2135 }
2136 else if (pCell->getFormula()->IsValue())
2137 {
2138 sal_uInt32 nFormat = m_pDocument->GetNumberFormat(aPos);
2139 if ( bFixedWidth || bSaveAsShown )
2140 {
2141 const Color* pDummy;
2142 aString = ScCellFormat::GetString(*pCell, nFormat, &pDummy, rFormatter, *m_pDocument);
2143 bString = bSaveAsShown && rFormatter.IsTextFormat( nFormat);
2144 }
2145 else
2146 {
2147 aString = ScCellFormat::GetInputString(*pCell, nFormat, rFormatter, *m_pDocument);
2148 bString = bForceQuotes = !bSaveNumberAsSuch;
2149 }
2150 }
2151 else
2152 {
2153 if ( bSaveAsShown )
2154 {
2155 sal_uInt32 nFormat = m_pDocument->GetNumberFormat(aPos);
2156 const Color* pDummy;
2157 aString = ScCellFormat::GetString(*pCell, nFormat, &pDummy, rFormatter, *m_pDocument);
2158 }
2159 else
2160 aString = pCell->getFormula()->GetString().getString();
2161 bString = true;
2162 }
2163 }
2164 break;
2165 case CELLTYPE_STRING :
2166 if ( bSaveAsShown )
2167 {
2168 sal_uInt32 nFormat = m_pDocument->GetNumberFormat(aPos);
2169 const Color* pDummy;
2170 aString = ScCellFormat::GetString(*pCell, nFormat, &pDummy, rFormatter, *m_pDocument);
2171 }
2172 else
2173 aString = pCell->getSharedString()->getString();
2174 bString = true;
2175 break;
2176 case CELLTYPE_EDIT :
2177 {
2178 const EditTextObject* pObj = pCell->getEditText();
2179 EditEngine& rEngine = m_pDocument->GetEditEngine();
2180 rEngine.SetText( *pObj);
2181 aString = rEngine.GetText(); // including LF
2182 bString = true;
2183 }
2184 break;
2185 case CELLTYPE_VALUE :
2186 {
2187 sal_uInt32 nFormat = m_pDocument->GetNumberFormat( nCol, nRow, nTab );
2188 if ( bFixedWidth || bSaveAsShown )
2189 {
2190 const Color* pDummy;
2191 aString = ScCellFormat::GetString(*pCell, nFormat, &pDummy, rFormatter, *m_pDocument);
2192 bString = bSaveAsShown && rFormatter.IsTextFormat( nFormat);
2193 }
2194 else
2195 {
2196 aString = ScCellFormat::GetInputString(*pCell, nFormat, rFormatter, *m_pDocument);
2197 bString = bForceQuotes = !bSaveNumberAsSuch;
2198 }
2199 }
2200 break;
2201 default:
2202 OSL_FAIL( "ScDocShell::AsciiSave: unknown CellType" );
2203 aString.clear();
2204 bString = false;
2205 }
2206
2207 if ( bFixedWidth )
2208 {
2209 SvxCellHorJustify eHorJust =
2210 m_pDocument->GetAttr( nCol, nRow, nTab, ATTR_HOR_JUSTIFY )->GetValue();
2211 lcl_ScDocShell_GetFixedWidthString( aString, *m_pDocument, nTab, nCol,
2212 !bString, eHorJust );
2213 rStream.WriteUnicodeOrByteText( aString );
2214 }
2215 else
2216 {
2217 OUString aUniString = aString;// TODO: remove that later
2218 if (!bString && cStrDelim != 0 && !aUniString.isEmpty())
2219 {
2220 sal_Unicode c = aUniString[0];
2221 bString = (c == cStrDelim || c == ' ' ||
2222 aUniString.endsWith(" ") ||
2223 aUniString.indexOf(cStrDelim) >= 0);
2224 if (!bString && cDelim != 0)
2225 bString = (aUniString.indexOf(cDelim) >= 0);
2226 }
2227 if ( bString )
2228 {
2229 if ( cStrDelim != 0 ) //@ BugId 55355
2230 {
2231 if ( eCharSet == RTL_TEXTENCODING_UNICODE )
2232 {
2233 bool bNeedQuotes = false;
2234 sal_Int32 nPos = getTextSepPos(
2235 aUniString, rAsciiOpt, cStrDelim, cDelim, bNeedQuotes);
2236
2237 escapeTextSep<OUString, OUStringBuffer>(
2238 nPos, OUString(cStrDelim), aUniString);
2239
2240 if ( bNeedQuotes || bForceQuotes )
2241 rStream.WriteUniOrByteChar( cStrDelim, eCharSet );
2242 write_uInt16s_FromOUString(rStream, aUniString);
2243 if ( bNeedQuotes || bForceQuotes )
2244 rStream.WriteUniOrByteChar( cStrDelim, eCharSet );
2245 }
2246 else
2247 {
2248 // This is nasty. The Unicode to byte encoding
2249 // may convert typographical quotation marks to ASCII
2250 // quotation marks, which may interfere with the delimiter,
2251 // so we have to escape delimiters after the string has
2252 // been encoded. Since this may happen also with UTF-8
2253 // encoded typographical quotation marks if such was
2254 // specified as a delimiter we have to check for the full
2255 // encoded delimiter string, not just one character.
2256 // Now for RTL_TEXTENCODING_ISO_2022_... and similar brain
2257 // dead encodings where one code point (and especially a
2258 // low ASCII value) may represent different characters, we
2259 // have to convert forth and back and forth again. Same for
2260 // UTF-7 since it is a context sensitive encoding too.
2261
2262 if ( bContextOrNotAsciiEncoding )
2263 {
2264 // to byte encoding
2265 OString aStrEnc = OUStringToOString(aUniString, eCharSet);
2266 // back to Unicode
2267 OUString aStrDec = OStringToOUString(aStrEnc, eCharSet);
2268
2269 // search on re-decoded string
2270 bool bNeedQuotes = false;
2271 sal_Int32 nPos = getTextSepPos(
2272 aStrDec, rAsciiOpt, aStrDelimDecoded, aDelimDecoded, bNeedQuotes);
2273
2274 escapeTextSep<OUString, OUStringBuffer>(
2275 nPos, aStrDelimDecoded, aStrDec);
2276
2277 // write byte re-encoded
2278 if ( bNeedQuotes || bForceQuotes )
2279 rStream.WriteUniOrByteChar( cStrDelim, eCharSet );
2280 rStream.WriteUnicodeOrByteText( aStrDec, eCharSet );
2281 if ( bNeedQuotes || bForceQuotes )
2282 rStream.WriteUniOrByteChar( cStrDelim, eCharSet );
2283 }
2284 else
2285 {
2286 OString aStrEnc = OUStringToOString(aUniString, eCharSet);
2287
2288 // search on encoded string
2289 bool bNeedQuotes = false;
2290 sal_Int32 nPos = getTextSepPos(
2291 aStrEnc, rAsciiOpt, aStrDelimEncoded, aDelimEncoded, bNeedQuotes);
2292
2293 escapeTextSep<OString, OStringBuffer>(
2294 nPos, aStrDelimEncoded, aStrEnc);
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 // ISO8859-1/MS_1252 encoding, comma, double quotes
2453
2454 ScImportOptions aDefOptions( ',', '"', RTL_TEXTENCODING_MS_1252 );
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 INetURLObject aDbtFile( pNameItem->GetValue(), INetProtocol::File );
2609 aDbtFile.setExtension(u"dbt");
2610
2611 // tdf#40713: don't lose dbt file
2612 // if aDbtFile corresponds exactly to aTmpFile, we just have to return
2613 if (aDbtFile.GetMainURL( INetURLObject::DecodeMechanism::Unambiguous ) ==
2615 {
2616 if (eError != ERRCODE_NONE && !GetError())
2617 SetError(eError);
2618 return bRet;
2619 }
2620
2621 if ( IsDocument( aDbtFile ) && !KillFile( aDbtFile ) )
2622 bRet = false;
2623 if ( bRet && !MoveFile( aTmpFile, aDbtFile ) )
2624 bRet = false;
2625 if ( !bRet )
2626 {
2627 KillFile( aTmpFile );
2628 if (eError == ERRCODE_NONE || eError.IsWarning())
2629 eError = SCERR_EXPORT_DATA;
2630 }
2631 }
2632 if (eError != ERRCODE_NONE && !GetError())
2633 SetError(eError);
2634 }
2635 }
2636 else if (aFltName == pFilterDif)
2637 {
2638 SvStream* pStream = rMed.GetOutStream();
2639 if (pStream)
2640 {
2641 OUString sItStr;
2642 SfxItemSet* pSet = rMed.GetItemSet();
2643 const SfxStringItem* pOptionsItem;
2644 if ( pSet &&
2645 (pOptionsItem = pSet->GetItemIfSet( SID_FILE_FILTEROPTIONS )) )
2646 {
2647 sItStr = pOptionsItem->GetValue();
2648 }
2649
2650 if (sItStr.isEmpty())
2651 {
2652 // default for DIF export (from API without options):
2653 // ISO8859-1/MS_1252 encoding
2654
2655 sItStr = ScGlobal::GetCharsetString( RTL_TEXTENCODING_MS_1252 );
2656 }
2657
2659 ScFormatFilter::Get().ScExportDif( *pStream, m_pDocument.get(), ScAddress(0,0,0),
2660 ScGlobal::GetCharsetValue(sItStr) );
2661 bRet = true;
2662
2663 if (m_pDocument->GetTableCount() > 1)
2664 if (!rMed.GetError())
2666 }
2667 }
2668 else if (aFltName == pFilterSylk)
2669 {
2670 SvStream* pStream = rMed.GetOutStream();
2671 if ( pStream )
2672 {
2674
2675 SCCOL nEndCol;
2676 SCROW nEndRow;
2677 m_pDocument->GetCellArea( 0, nEndCol, nEndRow );
2678 ScRange aRange( 0,0,0, nEndCol,nEndRow,0 );
2679
2680 ScImportExport aImExport( *m_pDocument, aRange );
2681 aImExport.SetFormulas( true );
2682 bRet = aImExport.ExportStream( *pStream, rMed.GetBaseURL( true ), SotClipboardFormatId::SYLK );
2683 }
2684 }
2685 else if (aFltName == pFilterHtml)
2686 {
2687 SvStream* pStream = rMed.GetOutStream();
2688 if ( pStream )
2689 {
2690 SfxItemSet* pSet = rMed.GetItemSet();
2691 OUString sFilterOptions;
2692
2693 if (const SfxStringItem* pOptionsItem = pSet->GetItemIfSet(SID_FILE_FILTEROPTIONS))
2694 sFilterOptions = pOptionsItem->GetValue();
2695
2697 ScImportExport aImExport(*m_pDocument);
2698 aImExport.SetStreamPath(rMed.GetName());
2699 aImExport.SetFilterOptions(sFilterOptions);
2700 bRet = aImExport.ExportStream(*pStream, rMed.GetBaseURL(true), SotClipboardFormatId::HTML);
2701 if (bRet && !aImExport.GetNonConvertibleChars().isEmpty())
2702 {
2705 aImExport.GetNonConvertibleChars(),
2706 DialogMask::ButtonsOk | DialogMask::MessageInfo));
2707 }
2708 }
2709 }
2710 else
2711 {
2712 if (GetError())
2714 }
2715 return bRet;
2716}
2717
2718bool ScDocShell::DoSaveCompleted( SfxMedium * pNewStor, bool bRegisterRecent )
2719{
2720 bool bRet = SfxObjectShell::DoSaveCompleted( pNewStor, bRegisterRecent );
2721
2722 // SfxHintId::ScDocSaved for change ReadOnly -> Read/Write
2723 Broadcast( SfxHint( SfxHintId::ScDocSaved ) );
2724 return bRet;
2725}
2726
2727bool ScDocShell::QuerySlotExecutable( sal_uInt16 nSlotId )
2728{
2729 // #i112634# ask VBA event handlers whether to save or print the document
2730
2731 using namespace ::com::sun::star::script::vba;
2732
2733 sal_Int32 nVbaEventId = VBAEventId::NO_EVENT;
2734 uno::Sequence< uno::Any > aArgs;
2735 switch( nSlotId )
2736 {
2737 case SID_SAVEDOC:
2738 case SID_SAVEASDOC:
2739 nVbaEventId = VBAEventId::WORKBOOK_BEFORESAVE;
2740 aArgs = { uno::Any(nSlotId == SID_SAVEASDOC) };
2741 break;
2742 case SID_PRINTDOC:
2743 case SID_PRINTDOCDIRECT:
2744 nVbaEventId = VBAEventId::WORKBOOK_BEFOREPRINT;
2745 break;
2746 }
2747
2748 bool bSlotExecutable = true;
2749 if( nVbaEventId != VBAEventId::NO_EVENT ) try
2750 {
2751 uno::Reference< XVBAEventProcessor > xEventProcessor( m_pDocument->GetVbaEventProcessor(), uno::UNO_SET_THROW );
2752 xEventProcessor->processVbaEvent( nVbaEventId, aArgs );
2753 }
2754 catch( util::VetoException& )
2755 {
2756 bSlotExecutable = false;
2757 }
2758 catch( uno::Exception& )
2759 {
2760 }
2761 return bSlotExecutable;
2762}
2763
2765{
2766 if(SC_MOD()->GetCurRefDlgId()>0)
2767 {
2768 SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this );
2769 if( pFrame )
2770 {
2771 SfxViewShell* p = pFrame->GetViewShell();
2772 ScTabViewShell* pViewSh = dynamic_cast< ScTabViewShell *>( p );
2773 if(pViewSh!=nullptr)
2774 {
2775 vcl::Window *pWin=pViewSh->GetWindow();
2776 if(pWin!=nullptr) pWin->GrabFocus();
2777 }
2778 }
2779
2780 return false;
2781 }
2782 if ( m_pDocument->IsInLinkUpdate() || m_pDocument->IsInInterpreter() )
2783 {
2784 ErrorMessage(STR_CLOSE_ERROR_LINK);
2785 return false;
2786 }
2787
2789
2790 // start 'Workbook_BeforeClose' VBA event handler for possible veto
2791 if( !IsInPrepareClose() )
2792 {
2793 try
2794 {
2795 uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents( m_pDocument->GetVbaEventProcessor(), uno::UNO_SET_THROW );
2796 uno::Sequence< uno::Any > aArgs;
2797 xVbaEvents->processVbaEvent( script::vba::VBAEventId::WORKBOOK_BEFORECLOSE, aArgs );
2798 }
2799 catch( util::VetoException& )
2800 {
2801 // if event processor throws VetoException, macro has vetoed close
2802 return false;
2803 }
2804 catch( uno::Exception& )
2805 {
2806 }
2807 }
2808 // end handler code
2809
2810 bool bRet = SfxObjectShell::PrepareClose( bUI );
2811 if (bRet) // true == close
2812 m_pDocument->EnableIdle(false); // Do not mess around with it anymore!
2813
2814 return bRet;
2815}
2816
2818{
2819 return pFilterSc50;
2820}
2821
2823{
2824 return pFilterHtml;
2825}
2826
2828{
2829 return pFilterHtmlWebQ;
2830}
2831
2833{
2835}
2836
2838{
2839 return pFilterLotus;
2840}
2841
2843{
2844 return pFilterDBase;
2845}
2846
2848{
2849 return pFilterDif;
2850}
2851
2852bool ScDocShell::HasAutomaticTableName( std::u16string_view rFilter )
2853{
2854 // sal_True for those filters that keep the default table name
2855 // (which is language specific)
2856
2857 return rFilter == SC_TEXT_CSV_FILTER_NAME
2858 || rFilter == pFilterLotus
2859 || rFilter == pFilterExcel4
2860 || rFilter == pFilterEx4Temp
2861 || rFilter == pFilterDBase
2862 || rFilter == pFilterDif
2863 || rFilter == pFilterSylk
2864 || rFilter == pFilterHtml
2865 || rFilter == pFilterRtf;
2866}
2867
2868std::unique_ptr<ScDocFunc> ScDocShell::CreateDocFunc()
2869{
2870 return std::make_unique<ScDocFuncDirect>( *this );
2871}
2872
2873ScDocShell::ScDocShell( const SfxModelFlags i_nSfxCreationFlags, const std::shared_ptr<ScDocument>& pDoc ) :
2874 SfxObjectShell( i_nSfxCreationFlags ),
2875 m_pDocument ( pDoc ? pDoc : std::make_shared<ScDocument>( SCDOCMODE_DOCUMENT, this )),
2876 m_aDdeTextFmt(OUString("TEXT")),
2877 m_nPrtToScreenFactor( 1.0 ),
2878 m_pImpl ( new DocShell_Impl ),
2879 m_bHeaderOn ( true ),
2880 m_bFooterOn ( true ),
2881 m_bIsEmpty ( true ),
2882 m_bIsInUndo ( false ),
2884 m_bUpdateEnabled ( true ),
2885 m_bUcalcTest ( false ),
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
3401{
3402 m_bUcalcTest = true;
3403}
3404
3405void ScDocShell::RegisterAutomationWorkbookObject(css::uno::Reference< ooo::vba::excel::XWorkbook > const& xWorkbook)
3406{
3407 mxAutomationWorkbookObject = xWorkbook;
3408}
3409
3410extern "C" SAL_DLLPUBLIC_EXPORT bool TestImportSLK(SvStream &rStream)
3411{
3412 ScDLL::Init();
3414 ScDocOptions aDocOpt = aDocument.GetDocOptions();
3415 aDocOpt.SetLookUpColRowNames(false);
3416 aDocument.SetDocOptions(aDocOpt);
3417 aDocument.MakeTable(0);
3418 aDocument.EnableExecuteLink(false);
3419 aDocument.SetInsertingFromOtherDoc(true);
3420 aDocument.SetImportingXML(true);
3421
3422 ScImportExport aImpEx(aDocument);
3423 return aImpEx.ImportStream(rStream, OUString(), SotClipboardFormatId::SYLK);
3424}
3425
3426extern "C" SAL_DLLPUBLIC_EXPORT bool TestImportDBF(SvStream &rStream)
3427{
3428 ScDLL::Init();
3429
3430 // we need a real file for this filter
3431
3432 // put it in an empty dir
3433 utl::TempFile aTmpDir(nullptr, true);
3434 aTmpDir.EnableKillingFile();
3435 OUString sTmpDir = aTmpDir.GetURL();
3436
3437 OUString sExtension(".dbf");
3438 utl::TempFile aTempInput(u"", true, &sExtension, &sTmpDir);
3439 aTempInput.EnableKillingFile();
3440
3441 SvStream* pInputStream = aTempInput.GetStream(StreamMode::WRITE);
3442 sal_uInt8 aBuffer[8192];
3443 while (auto nRead = rStream.ReadBytes(aBuffer, SAL_N_ELEMENTS(aBuffer)))
3444 pInputStream->WriteBytes(aBuffer, nRead);
3445 aTempInput.CloseStream();
3446
3447 SfxMedium aMedium(aTempInput.GetURL(), StreamMode::STD_READWRITE);
3448
3449 ScDocShellRef xDocShell = new ScDocShell(SfxModelFlags::EMBEDDED_OBJECT |
3450 SfxModelFlags::DISABLE_EMBEDDED_SCRIPTS |
3451 SfxModelFlags::DISABLE_DOCUMENT_RECOVERY);
3452
3453 xDocShell->DoInitNew();
3454
3455 ScDocument& rDoc = xDocShell->GetDocument();
3456
3457 ScDocOptions aDocOpt = rDoc.GetDocOptions();
3458 aDocOpt.SetLookUpColRowNames(false);
3459 rDoc.SetDocOptions(aDocOpt);
3460 rDoc.MakeTable(0);
3461 rDoc.EnableExecuteLink(false);
3462 rDoc.SetInsertingFromOtherDoc(true);
3463
3464 ScDocRowHeightUpdater::TabRanges aRecalcRanges(0, rDoc.MaxRow());
3465 std::map<SCCOL, ScColWidthParam> aColWidthParam;
3466 ErrCode eError = xDocShell->DBaseImport(aMedium.GetPhysicalName(), RTL_TEXTENCODING_IBM_850, aColWidthParam, aRecalcRanges.maRanges);
3467
3468 xDocShell->DoClose();
3469 xDocShell.clear();
3470
3471 return eError == ERRCODE_NONE;
3472}
3473
3474/* 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:457
ScDocShellModificator(const ScDocShellModificator &)=delete
ScDocShell & rDocShell
Definition: docsh.hxx:458
~ScDocShellModificator() COVERITY_NOEXCEPT_FALSE
Definition: docsh.cxx:3288
bool bAutoCalcShellDisabled
Definition: docsh.hxx:460
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:1725
PrepareSaveGuard(ScDocShell &rDocShell)
Definition: docsh.cxx:1701
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:573
static OUString GetHtmlFilterName()
Definition: docsh.cxx:2822
void PostPaintGridAll()
Definition: docsh3.cxx:183
virtual bool Save() override
Definition: docsh.cxx:1738
double m_nPrtToScreenFactor
Definition: docsh.hxx:86
SAL_DLLPRIVATE void ResetDrawObjectShell()
Definition: docsh2.cxx:165
static OUString GetDifFilterName()
Definition: docsh.cxx:2847
void DoHardRecalc()
Definition: docsh4.cxx:1511
static OUString GetLotusFilterName()
Definition: docsh.cxx:2837
bool m_bIsInplace
Definition: docsh.hxx:92
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:2727
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:84
SfxBindings * GetViewBindings()
Definition: docsh4.cxx:2627
bool m_bDocumentModifiedPending
Definition: docsh.hxx:95
void ErrorMessage(TranslateId pGlobStrId)
Definition: docsh5.cxx:70
std::unique_ptr< ScDocFunc > m_pDocFunc
Definition: docsh.hxx:88
static OUString GetAsciiFilterName()
Definition: docsh.cxx:2832
bool m_bHeaderOn
Definition: docsh.hxx:90
void AfterXMLLoading(bool bRet)
Definition: docsh.cxx:274
void AsciiSave(SvStream &rStream, const ScImportOptions &rOpt, SCTAB nTab)
Definition: docsh.cxx:1936
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 SetIsInUcalc()
Definition: docsh.cxx:3400
void RegisterAutomationWorkbookObject(css::uno::Reference< ooo::vba::excel::XWorkbook > const &xWorkbook)
Definition: docsh.cxx:3405
bool IsInUndo() const
Definition: docsh.hxx:354
SAL_DLLPRIVATE SCTAB GetSaveTab()
Definition: docsh.cxx:220
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:2718
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
bool m_bUcalcTest
Definition: docsh.hxx:97
SAL_DLLPRIVATE void InitItems()
Definition: docsh2.cxx:97
void GetDocStat(ScDocStat &rDocStat)
Definition: docsh.cxx:3059
virtual bool PrepareClose(bool bUI=true) override
Definition: docsh.cxx:2764
virtual bool LoadFrom(SfxMedium &rMedium) override
Definition: docsh.cxx:1076
void PostDataChanged()
Definition: docsh3.cxx:93
std::shared_ptr< ScDocument > m_pDocument
Definition: docsh.hxx:82
static SAL_DLLPRIVATE bool MoveFile(const INetURLObject &rSource, const INetURLObject &rDest)
Definition: docsh8.cxx:142
static OUString GetWebQueryFilterName()
Definition: docsh.cxx:2827
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:557
std::unique_ptr< ScPaintLockData > m_pPaintLockData
Definition: docsh.hxx:105
ScDrawLayer * MakeDrawLayer()
Definition: docsh2.cxx:172
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:87
sal_Int16 m_nCanUpdate
Definition: docsh.hxx:100
bool m_bFooterOn
Definition: docsh.hxx:91
virtual HiddenInformation GetHiddenInformationState(HiddenInformation nStates) override
Definition: docsh.cxx:232
ScTabViewShell * GetBestViewShell(bool bOnlyVisible=true)
Definition: docsh4.cxx:2608
bool m_bIsEmpty
Definition: docsh.hxx:93
void SetInUndo(bool bSet)
Definition: docsh.cxx:3054
static OUString GetDBaseFilterName()
Definition: docsh.cxx:2842
virtual bool SaveAs(SfxMedium &rMedium) override
Definition: docsh.cxx:1781
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:1775
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:213
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:473
std::unique_ptr< ScDBData > m_pOldAutoDBRange
Definition: docsh.hxx:102
virtual bool ConvertFrom(SfxMedium &rMedium) override
Definition: docsh.cxx:1127
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:2817
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:2852
void SetDocumentModifiedPending(bool bVal)
Definition: docsh.hxx:379
SAL_DLLPRIVATE std::unique_ptr< ScDocFunc > CreateDocFunc()
Definition: docsh.cxx:2868
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
Definition: docsh.cxx:645
ScSheetSaveData * GetSheetSaveData()
Definition: docsh.cxx:3102
virtual std::set< Color > GetDocColors() override
Definition: docsh.cxx:208
void BeforeXMLLoading()
Definition: docsh.cxx:259
bool m_bIsInUndo
Definition: docsh.hxx:94
bool m_bUpdateEnabled
Definition: docsh.hxx:96
virtual std::shared_ptr< SfxDocumentInfoDialog > CreateDocumentInfoDialog(weld::Window *pParent, const SfxItemSet &rSet) override
Definition: docsh.cxx: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:1660
SC_DLLPUBLIC sal_uInt16 GetColWidth(SCCOL nCol, SCTAB nTab, bool bHiddenAsZero=true) const
Definition: document.cxx:4177
void ClosingClipboardSource()
To be called at the clipboard document when closing a document that is the current clipboard source t...
Definition: documen2.cxx:331
bool IsIdleEnabled() const
Definition: document.hxx:2200
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:2486
SC_DLLPUBLIC void SetDocOptions(const ScDocOptions &rOpt)
Definition: documen3.cxx:1952
void EnableExecuteLink(bool bVal)
Definition: document.hxx:1599
@ TEMPORARY
normal calculation of dependencies
void EnableIdle(bool bDo)
Definition: document.hxx:2201
SC_DLLPUBLIC void MakeTable(SCTAB nTab, bool _bNeedsNameCheck=true)
Definition: document.cxx:170
void SetInsertingFromOtherDoc(bool bVal)
Definition: document.hxx:2216
sc::DocumentLinkManager & GetDocLinkManager()
Definition: documen2.cxx:240
void SetAutoCalcShellDisabled(bool bNew)
Definition: document.hxx:1411
bool IsAutoCalcShellDisabled() const
Definition: document.hxx:1412
SC_DLLPUBLIC const ScDocOptions & GetDocOptions() const
Definition: documen3.cxx:1946
bool IsImportingXML() const
Definition: document.hxx:2220
void BroadcastUno(const SfxHint &rHint)
Definition: documen3.cxx:952
Extended options held by an ScDocument containing additional settings for filters.
Definition: scextopt.hxx:77
void setAllCacheTableReferencedStati(bool bReferenced)
bool hasExternalData() const
virtual ErrCode ScExportExcel5(SfxMedium &, ScDocument *, ExportFormatExcel eFormat, rtl_TextEncoding eDest)=0
virtual ErrCode ScImportQuattroPro(SvStream *pStream, ScDocument &rDoc)=0
virtual ErrCode 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:2622
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:574
static rtl_TextEncoding GetCharsetValue(std::u16string_view rCharSet)
Definition: global.cxx:564
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:651
::tools::Long nLastColWidthExtra
Definition: global.hxx:584
static SC_DLLPUBLIC double nScreenPPTY
Vertical pixel per twips factor.
Definition: global.hxx:576
static OUString GetCharsetString(rtl_TextEncoding eVal)
Definition: global.cxx:592
static OUString GetErrorString(FormulaError nErrNumber)
Definition: global.cxx:311
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:423
bool IsOverflowRow() const
Definition: impex.hxx:150
bool ImportStream(SvStream &, const OUString &rBaseURL, SotClipboardFormatId)
Definition: impex.cxx:383
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:369
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:1075
weld::Window * GetDialogParent()
parent window for dialogs Problem: OLE Server!
Definition: tabvwshd.cxx:31
void UpdateLayerLocks()
Definition: tabview5.cxx:355
ScViewData & GetViewData()
Definition: tabview.hxx:333
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:717
bool Import(ImportFlags nMode, ErrCode &rError)
Definition: xmlwrap.cxx:285
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()
static SfxViewFrame * GetFirst(const SfxObjectShell *pDoc=nullptr, bool bOnlyVisible=true)
SfxFrame & GetFrame() const
bool isLOKMobilePhone() const
SfxViewFrame * GetViewFrame() const
static SfxViewShell * Current()
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)
OUString getString() const
virtual LockFileEntry GetLockData() override
static OUString getProductName()
OUString const & GetURL() const
void CloseStream()
void EnableKillingFile(bool bEnable=true)
SvStream * GetStream(StreamMode eMode)
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:82
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:165
constexpr OUStringLiteral pFilterDBase
Definition: docsh.cxx:164
SAL_DLLPUBLIC_EXPORT bool TestImportSLK(SvStream &rStream)
Definition: docsh.cxx:3410
constexpr OUStringLiteral pFilterHtmlWebQ
Definition: docsh.cxx:168
SAL_DLLPUBLIC_EXPORT bool TestImportDBF(SvStream &rStream)
Definition: docsh.cxx:3426
const char pFilterEx97Temp[]
Definition: docsh.cxx:163
constexpr OUStringLiteral pFilterLotus
Definition: docsh.cxx:154
static void lcl_parseHtmlFilterOption(const OUString &rOption, LanguageType &rLang, bool &rDateConvert)
Definition: docsh.cxx:1097
const char pFilterExcel97[]
Definition: docsh.cxx:162
const char16_t pFilterSylk[]
Definition: docsh.cxx:166
constexpr OUStringLiteral pFilterSc50
Definition: docsh.cxx:152
const char pFilterEx5Temp[]
Definition: docsh.cxx:159
const char pFilterEx95Temp[]
Definition: docsh.cxx:161
const char pFilterQPro6[]
Definition: docsh.cxx:155
const char16_t pFilterRtf[]
Definition: docsh.cxx:169
const char pFilterXML[]
Definition: docsh.cxx:153
constexpr OUStringLiteral pFilterHtml
Definition: docsh.cxx:167
const char pFilterExcel5[]
Definition: docsh.cxx:158
const char16_t pFilterEx4Temp[]
Definition: docsh.cxx:157
const char pFilterExcel95[]
Definition: docsh.cxx:160
const char16_t pFilterExcel4[]
Definition: docsh.cxx:156
@ 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:270
@ CELLTYPE_EDIT
Definition: global.hxx:275
@ CELLTYPE_STRING
Definition: global.hxx:273
@ CELLTYPE_FORMULA
Definition: global.hxx:274
@ CELLTYPE_NONE
Definition: global.hxx:271
@ CELLTYPE_VALUE
Definition: global.hxx:272
constexpr OUStringLiteral SC_TEXT_CSV_FILTER_NAME
Definition: global.hxx:62
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 ContentProperties & rData
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
void(* f)(TrueTypeTable *)
sal_Int32 toInt32(OUString const &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:449
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.
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