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