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 <config_features.h> | ||||||||
21 | |||||||||
22 | #include <boost/property_tree/json_parser.hpp> | ||||||||
23 | |||||||||
24 | #include <com/sun/star/frame/Desktop.hpp> | ||||||||
25 | |||||||||
26 | using namespace ::com::sun::star; | ||||||||
27 | |||||||||
28 | #include <scitems.hxx> | ||||||||
29 | #include <editeng/flstitem.hxx> | ||||||||
30 | #include <sfx2/fcontnr.hxx> | ||||||||
31 | #include <sfx2/infobar.hxx> | ||||||||
32 | #include <sfx2/objface.hxx> | ||||||||
33 | #include <sfx2/docfile.hxx> | ||||||||
34 | #include <sfx2/docfilt.hxx> | ||||||||
35 | #include <svtools/ehdl.hxx> | ||||||||
36 | #include <svtools/langtab.hxx> | ||||||||
37 | #include <basic/sbxcore.hxx> | ||||||||
38 | #include <basic/sberrors.hxx> | ||||||||
39 | #include <svtools/sfxecode.hxx> | ||||||||
40 | #include <svx/ofaitem.hxx> | ||||||||
41 | #include <svl/stritem.hxx> | ||||||||
42 | #include <svl/whiter.hxx> | ||||||||
43 | #include <vcl/button.hxx> | ||||||||
44 | #include <vcl/svapp.hxx> | ||||||||
45 | #include <vcl/weld.hxx> | ||||||||
46 | #include <svx/dataaccessdescriptor.hxx> | ||||||||
47 | #include <svx/drawitem.hxx> | ||||||||
48 | #include <svx/fmshell.hxx> | ||||||||
49 | #include <sfx2/passwd.hxx> | ||||||||
50 | #include <sfx2/filedlghelper.hxx> | ||||||||
51 | #include <sfx2/dispatch.hxx> | ||||||||
52 | #include <sfx2/sfxdlg.hxx> | ||||||||
53 | #include <svl/PasswordHelper.hxx> | ||||||||
54 | #include <svl/documentlockfile.hxx> | ||||||||
55 | #include <svl/sharecontrolfile.hxx> | ||||||||
56 | #include <unotools/securityoptions.hxx> | ||||||||
57 | #include <LibreOfficeKit/LibreOfficeKitEnums.h> | ||||||||
58 | #include <sal/log.hxx> | ||||||||
59 | #include <unotools/charclass.hxx> | ||||||||
60 | |||||||||
61 | #include <comphelper/lok.hxx> | ||||||||
62 | #include <comphelper/processfactory.hxx> | ||||||||
63 | #include <docuno.hxx> | ||||||||
64 | |||||||||
65 | #include <docsh.hxx> | ||||||||
66 | #include "docshimp.hxx" | ||||||||
67 | #include <docfunc.hxx> | ||||||||
68 | #include <scres.hrc> | ||||||||
69 | #include <strings.hrc> | ||||||||
70 | #include <stlsheet.hxx> | ||||||||
71 | #include <stlpool.hxx> | ||||||||
72 | #include <appoptio.hxx> | ||||||||
73 | #include <globstr.hrc> | ||||||||
74 | #include <global.hxx> | ||||||||
75 | #include <dbdocfun.hxx> | ||||||||
76 | #include <printfun.hxx> | ||||||||
77 | #include <viewdata.hxx> | ||||||||
78 | #include <tabvwsh.hxx> | ||||||||
79 | #include <impex.hxx> | ||||||||
80 | #include <undodat.hxx> | ||||||||
81 | #include <undocell.hxx> | ||||||||
82 | #include <inputhdl.hxx> | ||||||||
83 | #include <dbdata.hxx> | ||||||||
84 | #include <servobj.hxx> | ||||||||
85 | #include <rangenam.hxx> | ||||||||
86 | #include <scmod.hxx> | ||||||||
87 | #include <chgviset.hxx> | ||||||||
88 | #include <reffact.hxx> | ||||||||
89 | #include <chartlis.hxx> | ||||||||
90 | #include <chartpos.hxx> | ||||||||
91 | #include <waitoff.hxx> | ||||||||
92 | #include <tablink.hxx> | ||||||||
93 | #include <drwlayer.hxx> | ||||||||
94 | #include <docoptio.hxx> | ||||||||
95 | #include <undostyl.hxx> | ||||||||
96 | #include <rangeseq.hxx> | ||||||||
97 | #include <chgtrack.hxx> | ||||||||
98 | #include <com/sun/star/document/UpdateDocMode.hpp> | ||||||||
99 | #include <scresid.hxx> | ||||||||
100 | #include <scabstdlg.hxx> | ||||||||
101 | #include <sharedocdlg.hxx> | ||||||||
102 | #include <conditio.hxx> | ||||||||
103 | #include <sheetevents.hxx> | ||||||||
104 | #include <formulacell.hxx> | ||||||||
105 | #include <documentlinkmgr.hxx> | ||||||||
106 | #include <memory> | ||||||||
107 | #include <sfx2/notebookbar/SfxNotebookBar.hxx> | ||||||||
108 | #include <helpids.h> | ||||||||
109 | #include <editeng/eeitem.hxx> | ||||||||
110 | #include <editeng/langitem.hxx> | ||||||||
111 | |||||||||
112 | #include <svx/xdef.hxx> | ||||||||
113 | |||||||||
114 | void ScDocShell::ReloadAllLinks() | ||||||||
115 | { | ||||||||
116 | m_aDocument.SetLinkFormulaNeedingCheck(false); | ||||||||
117 | getEmbeddedObjectContainer().setUserAllowsLinkUpdate(true); | ||||||||
118 | |||||||||
119 | ReloadTabLinks(); | ||||||||
120 | weld::Window *pDialogParent = GetActiveDialogParent(); | ||||||||
121 | m_aDocument.UpdateExternalRefLinks(pDialogParent); | ||||||||
122 | |||||||||
123 | bool bAnyDde = m_aDocument.GetDocLinkManager().updateDdeOrOleOrWebServiceLinks(pDialogParent); | ||||||||
124 | |||||||||
125 | if (bAnyDde) | ||||||||
126 | { | ||||||||
127 | // calculate formulas and paint like in the TrackTimeHdl | ||||||||
128 | m_aDocument.TrackFormulas(); | ||||||||
129 | Broadcast(SfxHint(SfxHintId::ScDataChanged)); | ||||||||
130 | |||||||||
131 | // Should FID_DATACHANGED become asynchronous some time | ||||||||
132 | // (e.g., with Invalidate at Window), an update needs to be forced here. | ||||||||
133 | } | ||||||||
134 | |||||||||
135 | m_aDocument.UpdateAreaLinks(); | ||||||||
136 | } | ||||||||
137 | |||||||||
138 | IMPL_LINK_NOARG( ScDocShell, ReloadAllLinksHdl, weld::Button&, void )void ScDocShell::LinkStubReloadAllLinksHdl(void * instance, weld ::Button& data) { return static_cast<ScDocShell *>( instance)->ReloadAllLinksHdl(data); } void ScDocShell::ReloadAllLinksHdl (__attribute__ ((unused)) weld::Button&) | ||||||||
139 | { | ||||||||
140 | ReloadAllLinks(); | ||||||||
141 | |||||||||
142 | ScTabViewShell* pViewSh = GetBestViewShell(); | ||||||||
143 | SfxViewFrame* pViewFrame = pViewSh ? pViewSh->GetFrame() : nullptr; | ||||||||
144 | if (pViewFrame) | ||||||||
145 | pViewFrame->RemoveInfoBar("enablecontent"); | ||||||||
146 | SAL_WARN_IF(!pViewFrame, "sc", "expected there to be a ViewFrame")do { if (true && (!pViewFrame)) { switch (sal_detail_log_report (::SAL_DETAIL_LOG_LEVEL_WARN, "sc")) { case SAL_DETAIL_LOG_ACTION_IGNORE : break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail ::getResult( ::sal::detail::StreamStart() << "expected there to be a ViewFrame" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sc" ), ("/home/maarten/src/libreoffice/core/sc/source/ui/docshell/docsh4.cxx" ":" "146" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "expected there to be a ViewFrame"), 0 ); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "expected there to be a ViewFrame"; ::sal::detail:: log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sc"), ("/home/maarten/src/libreoffice/core/sc/source/ui/docshell/docsh4.cxx" ":" "146" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "expected there to be a ViewFrame") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sc"), ("/home/maarten/src/libreoffice/core/sc/source/ui/docshell/docsh4.cxx" ":" "146" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "expected there to be a ViewFrame"), 0 ); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "expected there to be a ViewFrame"; ::sal::detail:: log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sc"), ("/home/maarten/src/libreoffice/core/sc/source/ui/docshell/docsh4.cxx" ":" "146" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||||
147 | } | ||||||||
148 | |||||||||
149 | ScLkUpdMode ScDocShell::GetLinkUpdateModeState() const | ||||||||
150 | { | ||||||||
151 | const ScDocument& rDoc = GetDocument(); | ||||||||
152 | |||||||||
153 | ScLkUpdMode nSet = rDoc.GetLinkMode(); | ||||||||
154 | |||||||||
155 | if (nSet == LM_UNKNOWN) | ||||||||
156 | { | ||||||||
157 | ScAppOptions aAppOptions = SC_MOD()( static_cast<ScModule*>(SfxApplication::GetModule(SfxToolsModule ::Calc)) )->GetAppOptions(); | ||||||||
158 | nSet = aAppOptions.GetLinkMode(); | ||||||||
159 | } | ||||||||
160 | |||||||||
161 | if (m_nCanUpdate == css::document::UpdateDocMode::NO_UPDATE) | ||||||||
162 | nSet = LM_NEVER; | ||||||||
163 | else if (m_nCanUpdate == css::document::UpdateDocMode::FULL_UPDATE) | ||||||||
164 | nSet = LM_ALWAYS; | ||||||||
165 | |||||||||
166 | if (nSet == LM_ALWAYS | ||||||||
167 | && !(SvtSecurityOptions().isTrustedLocationUriForUpdatingLinks( | ||||||||
168 | GetMedium() == nullptr ? OUString() : GetMedium()->GetName()) | ||||||||
169 | || (IsDocShared() | ||||||||
170 | && SvtSecurityOptions().isTrustedLocationUriForUpdatingLinks( | ||||||||
171 | GetSharedFileURL())))) | ||||||||
172 | { | ||||||||
173 | nSet = LM_ON_DEMAND; | ||||||||
174 | } | ||||||||
175 | if (m_nCanUpdate == css::document::UpdateDocMode::QUIET_UPDATE | ||||||||
176 | && nSet == LM_ON_DEMAND) | ||||||||
177 | { | ||||||||
178 | nSet = LM_NEVER; | ||||||||
179 | } | ||||||||
180 | |||||||||
181 | return nSet; | ||||||||
182 | } | ||||||||
183 | |||||||||
184 | void ScDocShell::Execute( SfxRequest& rReq ) | ||||||||
185 | { | ||||||||
186 | const SfxItemSet* pReqArgs = rReq.GetArgs(); | ||||||||
187 | SfxBindings* pBindings = GetViewBindings(); | ||||||||
188 | bool bUndo (m_aDocument.IsUndoEnabled()); | ||||||||
189 | |||||||||
190 | sal_uInt16 nSlot = rReq.GetSlot(); | ||||||||
191 | switch ( nSlot ) | ||||||||
| |||||||||
192 | { | ||||||||
193 | case SID_SC_SETTEXT((((26000 + 521) + 50))+46): | ||||||||
194 | { | ||||||||
195 | const SfxPoolItem* pColItem; | ||||||||
196 | const SfxPoolItem* pRowItem; | ||||||||
197 | const SfxPoolItem* pTabItem; | ||||||||
198 | const SfxPoolItem* pTextItem; | ||||||||
199 | if( pReqArgs && pReqArgs->HasItem( FN_PARAM_1((20000 + 1100)+60), &pColItem ) && | ||||||||
200 | pReqArgs->HasItem( FN_PARAM_2((20000 + 1100)+61), &pRowItem ) && | ||||||||
201 | pReqArgs->HasItem( FN_PARAM_3((20000 + 1100)+62), &pTabItem ) && | ||||||||
202 | pReqArgs->HasItem( SID_SC_SETTEXT((((26000 + 521) + 50))+46), &pTextItem ) ) | ||||||||
203 | { | ||||||||
204 | // parameters are 1-based !!! | ||||||||
205 | SCCOL nCol = static_cast<const SfxInt16Item*>(pColItem)->GetValue() - 1; | ||||||||
206 | SCROW nRow = static_cast<const SfxInt32Item*>(pRowItem)->GetValue() - 1; | ||||||||
207 | SCTAB nTab = static_cast<const SfxInt16Item*>(pTabItem)->GetValue() - 1; | ||||||||
208 | |||||||||
209 | SCTAB nTabCount = m_aDocument.GetTableCount(); | ||||||||
210 | if ( m_aDocument.ValidCol(nCol) && m_aDocument.ValidRow(nRow) && ValidTab(nTab,nTabCount) ) | ||||||||
211 | { | ||||||||
212 | if ( m_aDocument.IsBlockEditable( nTab, nCol,nRow, nCol, nRow ) ) | ||||||||
213 | { | ||||||||
214 | OUString aVal = static_cast<const SfxStringItem*>(pTextItem)->GetValue(); | ||||||||
215 | m_aDocument.SetString( nCol, nRow, nTab, aVal ); | ||||||||
216 | |||||||||
217 | PostPaintCell( nCol, nRow, nTab ); | ||||||||
218 | SetDocumentModified(); | ||||||||
219 | |||||||||
220 | rReq.Done(); | ||||||||
221 | break; | ||||||||
222 | } | ||||||||
223 | else // protected cell | ||||||||
224 | { | ||||||||
225 | #if HAVE_FEATURE_SCRIPTING1 | ||||||||
226 | SbxBase::SetError( ERRCODE_BASIC_BAD_PARAMETERErrCode( ErrCodeArea::Sbx, ErrCodeClass::Runtime, 7) ); //! which error ? | ||||||||
227 | #endif | ||||||||
228 | break; | ||||||||
229 | } | ||||||||
230 | } | ||||||||
231 | } | ||||||||
232 | #if HAVE_FEATURE_SCRIPTING1 | ||||||||
233 | SbxBase::SetError( ERRCODE_BASIC_NO_OBJECTErrCode( ErrCodeArea::Sbx, ErrCodeClass::Runtime, 10) ); | ||||||||
234 | #endif | ||||||||
235 | } | ||||||||
236 | break; | ||||||||
237 | |||||||||
238 | case SID_SBA_IMPORT((((((((((((((26000 + 200) + 20)) + 20)) + 20)) + 25)) + 22)) + 20)) + 22): | ||||||||
239 | { | ||||||||
240 | if (pReqArgs) | ||||||||
241 | { | ||||||||
242 | const SfxPoolItem* pItem; | ||||||||
243 | svx::ODataAccessDescriptor aDesc; | ||||||||
244 | if ( pReqArgs->GetItemState( nSlot, true, &pItem ) == SfxItemState::SET ) | ||||||||
245 | { | ||||||||
246 | uno::Any aAny = static_cast<const SfxUnoAnyItem*>(pItem)->GetValue(); | ||||||||
247 | uno::Sequence<beans::PropertyValue> aProperties; | ||||||||
248 | if ( aAny >>= aProperties ) | ||||||||
249 | aDesc.initializeFrom( aProperties ); | ||||||||
250 | } | ||||||||
251 | |||||||||
252 | OUString sTarget; | ||||||||
253 | if ( pReqArgs->GetItemState( FN_PARAM_1((20000 + 1100)+60), true, &pItem ) == SfxItemState::SET ) | ||||||||
254 | sTarget = static_cast<const SfxStringItem*>(pItem)->GetValue(); | ||||||||
255 | |||||||||
256 | bool bIsNewArea = true; // Default sal_True (no inquiry) | ||||||||
257 | if ( pReqArgs->GetItemState( FN_PARAM_2((20000 + 1100)+61), true, &pItem ) == SfxItemState::SET ) | ||||||||
258 | bIsNewArea = static_cast<const SfxBoolItem*>(pItem)->GetValue(); | ||||||||
259 | |||||||||
260 | // if necessary, create new database area | ||||||||
261 | bool bMakeArea = false; | ||||||||
262 | if (bIsNewArea) | ||||||||
263 | { | ||||||||
264 | ScDBCollection* pDBColl = m_aDocument.GetDBCollection(); | ||||||||
265 | if ( !pDBColl || !pDBColl->getNamedDBs().findByUpperName(ScGlobal::getCharClassPtr()->uppercase(sTarget)) ) | ||||||||
266 | { | ||||||||
267 | ScAddress aPos; | ||||||||
268 | if ( aPos.Parse( sTarget, m_aDocument, m_aDocument.GetAddressConvention() ) & ScRefFlags::VALID ) | ||||||||
269 | { | ||||||||
270 | bMakeArea = true; | ||||||||
271 | if (bUndo) | ||||||||
272 | { | ||||||||
273 | OUString aStrImport = ScResId( STR_UNDO_IMPORTDATAreinterpret_cast<char const *>("STR_UNDO_IMPORTDATA" "\004" u8"Importing") ); | ||||||||
274 | ViewShellId nViewShellId(-1); | ||||||||
275 | if (ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell()) | ||||||||
276 | nViewShellId = pViewSh->GetViewShellId(); | ||||||||
277 | GetUndoManager()->EnterListAction( aStrImport, aStrImport, 0, nViewShellId ); | ||||||||
278 | } | ||||||||
279 | |||||||||
280 | ScDBData* pDBData = GetDBData( ScRange(aPos), SC_DB_IMPORT, ScGetDBSelection::Keep ); | ||||||||
281 | OSL_ENSURE(pDBData, "Cannot create DB data")do { if (true && (!(pDBData))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/ui/docshell/docsh4.cxx" ":" "281" ": "), "%s", "Cannot create DB data"); } } while ( false); | ||||||||
282 | sTarget = pDBData->GetName(); | ||||||||
283 | } | ||||||||
284 | } | ||||||||
285 | } | ||||||||
286 | |||||||||
287 | // inquire, before old DB range gets overwritten | ||||||||
288 | bool bDo = true; | ||||||||
289 | if (!bIsNewArea) | ||||||||
290 | { | ||||||||
291 | OUString aTemplate = ScResId( STR_IMPORT_REPLACEreinterpret_cast<char const *>("STR_IMPORT_REPLACE" "\004" u8"Do you want to replace the contents of #?") ); | ||||||||
292 | OUString aMessage = aTemplate.getToken( 0, '#' ) | ||||||||
293 | + sTarget | ||||||||
294 | + aTemplate.getToken( 1, '#' ); | ||||||||
295 | |||||||||
296 | std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(nullptr, | ||||||||
297 | VclMessageType::Question, VclButtonsType::YesNo, | ||||||||
298 | aMessage)); | ||||||||
299 | xQueryBox->set_default_response(RET_YES); | ||||||||
300 | bDo = xQueryBox->run() == RET_YES; | ||||||||
301 | } | ||||||||
302 | |||||||||
303 | if (bDo) | ||||||||
304 | { | ||||||||
305 | ScDBDocFunc(*this).UpdateImport( sTarget, aDesc ); | ||||||||
306 | rReq.Done(); | ||||||||
307 | |||||||||
308 | // UpdateImport also updates the internal operations | ||||||||
309 | } | ||||||||
310 | else | ||||||||
311 | rReq.Ignore(); | ||||||||
312 | |||||||||
313 | if ( bMakeArea && bUndo) | ||||||||
314 | GetUndoManager()->LeaveListAction(); | ||||||||
315 | } | ||||||||
316 | else | ||||||||
317 | { | ||||||||
318 | OSL_FAIL( "arguments expected" )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/docsh4.cxx" ":" "318" ": "), "%s", "arguments expected"); } } while (false ); | ||||||||
319 | } | ||||||||
320 | } | ||||||||
321 | break; | ||||||||
322 | |||||||||
323 | case SID_CHART_SOURCE((26000 + 100) + 25): | ||||||||
324 | case SID_CHART_ADDSOURCE((26000 + 100) + 27): | ||||||||
325 | if (pReqArgs) | ||||||||
326 | { | ||||||||
327 | ScDocument& rDoc = GetDocument(); | ||||||||
328 | const SfxPoolItem* pItem; | ||||||||
329 | OUString aChartName, aRangeName; | ||||||||
330 | |||||||||
331 | ScRange aSingleRange; | ||||||||
332 | ScRangeListRef aRangeListRef; | ||||||||
333 | bool bMultiRange = false; | ||||||||
334 | |||||||||
335 | bool bColHeaders = true; | ||||||||
336 | bool bRowHeaders = true; | ||||||||
337 | bool bColInit = false; | ||||||||
338 | bool bRowInit = false; | ||||||||
339 | bool bAddRange = (nSlot == SID_CHART_ADDSOURCE((26000 + 100) + 27)); | ||||||||
340 | |||||||||
341 | if( pReqArgs->HasItem( SID_CHART_NAME((26000 + 100) + 26), &pItem ) ) | ||||||||
342 | aChartName = static_cast<const SfxStringItem*>(pItem)->GetValue(); | ||||||||
343 | |||||||||
344 | if( pReqArgs->HasItem( SID_CHART_SOURCE((26000 + 100) + 25), &pItem ) ) | ||||||||
345 | aRangeName = static_cast<const SfxStringItem*>(pItem)->GetValue(); | ||||||||
346 | |||||||||
347 | if( pReqArgs->HasItem( FN_PARAM_1((20000 + 1100)+60), &pItem ) ) | ||||||||
348 | { | ||||||||
349 | bColHeaders = static_cast<const SfxBoolItem*>(pItem)->GetValue(); | ||||||||
350 | bColInit = true; | ||||||||
351 | } | ||||||||
352 | if( pReqArgs->HasItem( FN_PARAM_2((20000 + 1100)+61), &pItem ) ) | ||||||||
353 | { | ||||||||
354 | bRowHeaders = static_cast<const SfxBoolItem*>(pItem)->GetValue(); | ||||||||
355 | bRowInit = true; | ||||||||
356 | } | ||||||||
357 | |||||||||
358 | ScAddress::Details aDetails(rDoc.GetAddressConvention(), 0, 0); | ||||||||
359 | bool bValid = (aSingleRange.ParseAny(aRangeName, rDoc, aDetails) & ScRefFlags::VALID) == ScRefFlags::ZERO; | ||||||||
360 | if (!bValid) | ||||||||
361 | { | ||||||||
362 | aRangeListRef = new ScRangeList; | ||||||||
363 | aRangeListRef->Parse( aRangeName, rDoc ); | ||||||||
364 | if ( !aRangeListRef->empty() ) | ||||||||
365 | { | ||||||||
366 | bMultiRange = true; | ||||||||
367 | aSingleRange = aRangeListRef->front(); // for header | ||||||||
368 | bValid = true; | ||||||||
369 | } | ||||||||
370 | else | ||||||||
371 | aRangeListRef.clear(); | ||||||||
372 | } | ||||||||
373 | |||||||||
374 | ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell(); | ||||||||
375 | if (pViewSh && bValid && !aChartName.isEmpty() ) | ||||||||
376 | { | ||||||||
377 | weld::Window* pParent = pViewSh->GetFrameWeld(); | ||||||||
378 | |||||||||
379 | SCCOL nCol1 = aSingleRange.aStart.Col(); | ||||||||
380 | SCROW nRow1 = aSingleRange.aStart.Row(); | ||||||||
381 | SCCOL nCol2 = aSingleRange.aEnd.Col(); | ||||||||
382 | SCROW nRow2 = aSingleRange.aEnd.Row(); | ||||||||
383 | SCTAB nTab = aSingleRange.aStart.Tab(); | ||||||||
384 | |||||||||
385 | //! limit always or not at all ??? | ||||||||
386 | if (!bMultiRange) | ||||||||
387 | m_aDocument.LimitChartArea( nTab, nCol1,nRow1, nCol2,nRow2 ); | ||||||||
388 | |||||||||
389 | // Dialog for column/row headers | ||||||||
390 | bool bOk = true; | ||||||||
391 | if ( !bAddRange && ( !bColInit || !bRowInit ) ) | ||||||||
392 | { | ||||||||
393 | ScChartPositioner aChartPositioner( m_aDocument, nTab, nCol1,nRow1, nCol2,nRow2 ); | ||||||||
394 | if (!bColInit) | ||||||||
395 | bColHeaders = aChartPositioner.HasColHeaders(); | ||||||||
396 | if (!bRowInit) | ||||||||
397 | bRowHeaders = aChartPositioner.HasRowHeaders(); | ||||||||
398 | |||||||||
399 | ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create(); | ||||||||
400 | |||||||||
401 | ScopedVclPtr<AbstractScColRowLabelDlg> pDlg(pFact->CreateScColRowLabelDlg(pParent, bRowHeaders, bColHeaders)); | ||||||||
402 | if ( pDlg->Execute() == RET_OK ) | ||||||||
403 | { | ||||||||
404 | bColHeaders = pDlg->IsRow(); | ||||||||
405 | bRowHeaders = pDlg->IsCol(); | ||||||||
406 | |||||||||
407 | rReq.AppendItem(SfxBoolItem(FN_PARAM_1((20000 + 1100)+60), bColHeaders)); | ||||||||
408 | rReq.AppendItem(SfxBoolItem(FN_PARAM_2((20000 + 1100)+61), bRowHeaders)); | ||||||||
409 | } | ||||||||
410 | else | ||||||||
411 | bOk = false; | ||||||||
412 | } | ||||||||
413 | |||||||||
414 | if (bOk) // execute | ||||||||
415 | { | ||||||||
416 | if (bMultiRange) | ||||||||
417 | { | ||||||||
418 | if (bUndo) | ||||||||
419 | { | ||||||||
420 | GetUndoManager()->AddUndoAction( | ||||||||
421 | std::make_unique<ScUndoChartData>( this, aChartName, aRangeListRef, | ||||||||
422 | bColHeaders, bRowHeaders, bAddRange ) ); | ||||||||
423 | } | ||||||||
424 | m_aDocument.UpdateChartArea( aChartName, aRangeListRef, | ||||||||
425 | bColHeaders, bRowHeaders, bAddRange ); | ||||||||
426 | } | ||||||||
427 | else | ||||||||
428 | { | ||||||||
429 | ScRange aNewRange( nCol1,nRow1,nTab, nCol2,nRow2,nTab ); | ||||||||
430 | if (bUndo) | ||||||||
431 | { | ||||||||
432 | GetUndoManager()->AddUndoAction( | ||||||||
433 | std::make_unique<ScUndoChartData>( this, aChartName, aNewRange, | ||||||||
434 | bColHeaders, bRowHeaders, bAddRange ) ); | ||||||||
435 | } | ||||||||
436 | m_aDocument.UpdateChartArea( aChartName, aNewRange, | ||||||||
437 | bColHeaders, bRowHeaders, bAddRange ); | ||||||||
438 | } | ||||||||
439 | } | ||||||||
440 | } | ||||||||
441 | else | ||||||||
442 | { | ||||||||
443 | OSL_FAIL("UpdateChartArea: no ViewShell or wrong data")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/docsh4.cxx" ":" "443" ": "), "%s", "UpdateChartArea: no ViewShell or wrong data" ); } } while (false); | ||||||||
444 | } | ||||||||
445 | rReq.Done(); | ||||||||
446 | } | ||||||||
447 | else | ||||||||
448 | { | ||||||||
449 | OSL_FAIL("SID_CHART_SOURCE without arguments")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/docsh4.cxx" ":" "449" ": "), "%s", "SID_CHART_SOURCE without arguments") ; } } while (false); | ||||||||
450 | } | ||||||||
451 | break; | ||||||||
452 | |||||||||
453 | case FID_AUTO_CALC((((((((((((26000 + 200) + 20)) + 20)) + 20)) + 25)) + 22)) + 3): | ||||||||
454 | { | ||||||||
455 | bool bNewVal; | ||||||||
456 | const SfxPoolItem* pItem; | ||||||||
457 | if ( pReqArgs && SfxItemState::SET == pReqArgs->GetItemState( nSlot, true, &pItem ) ) | ||||||||
458 | bNewVal = static_cast<const SfxBoolItem*>(pItem)->GetValue(); | ||||||||
459 | else | ||||||||
460 | bNewVal = !m_aDocument.GetAutoCalc(); // Toggle for menu | ||||||||
461 | m_aDocument.SetAutoCalc( bNewVal ); | ||||||||
462 | SetDocumentModified(); | ||||||||
463 | if (pBindings) | ||||||||
464 | { | ||||||||
465 | pBindings->Invalidate( FID_AUTO_CALC((((((((((((26000 + 200) + 20)) + 20)) + 20)) + 25)) + 22)) + 3) ); | ||||||||
466 | } | ||||||||
467 | rReq.AppendItem( SfxBoolItem( FID_AUTO_CALC((((((((((((26000 + 200) + 20)) + 20)) + 20)) + 25)) + 22)) + 3), bNewVal ) ); | ||||||||
468 | rReq.Done(); | ||||||||
469 | } | ||||||||
470 | break; | ||||||||
471 | case FID_RECALC((((((((((((26000 + 200) + 20)) + 20)) + 20)) + 25)) + 22)) + 4): | ||||||||
472 | DoRecalc( rReq.IsAPI() ); | ||||||||
473 | rReq.Done(); | ||||||||
474 | break; | ||||||||
475 | case FID_HARD_RECALC((((((((((((26000 + 200) + 20)) + 20)) + 20)) + 25)) + 22)) + 18): | ||||||||
476 | DoHardRecalc(); | ||||||||
477 | rReq.Done(); | ||||||||
478 | break; | ||||||||
479 | case SID_UPDATETABLINKS((26000) + 72): | ||||||||
480 | { | ||||||||
481 | ScLkUpdMode nSet = GetLinkUpdateModeState(); | ||||||||
482 | |||||||||
483 | if (nSet == LM_ALWAYS) | ||||||||
484 | { | ||||||||
485 | ReloadAllLinks(); | ||||||||
486 | rReq.Done(); | ||||||||
487 | } | ||||||||
488 | else if (nSet == LM_NEVER) | ||||||||
489 | { | ||||||||
490 | getEmbeddedObjectContainer().setUserAllowsLinkUpdate(false); | ||||||||
491 | rReq.Ignore(); | ||||||||
492 | } | ||||||||
493 | else if (nSet == LM_ON_DEMAND) | ||||||||
494 | { | ||||||||
495 | ScTabViewShell* pViewSh = GetBestViewShell(); | ||||||||
496 | SfxViewFrame* pViewFrame = pViewSh ? pViewSh->GetFrame() : nullptr; | ||||||||
497 | if (pViewFrame) | ||||||||
498 | { | ||||||||
499 | pViewFrame->RemoveInfoBar("enablecontent"); | ||||||||
500 | auto pInfoBar = pViewFrame->AppendInfoBar("enablecontent", "", ScResId(STR_RELOAD_TABLESreinterpret_cast<char const *>("STR_RELOAD_TABLES" "\004" u8"Automatic update of external links has been disabled.")), InfobarType::WARNING); | ||||||||
501 | if (pInfoBar) | ||||||||
502 | { | ||||||||
503 | weld::Button& rBtn = pInfoBar->addButton(); | ||||||||
504 | rBtn.set_label(ScResId(STR_ENABLE_CONTENTreinterpret_cast<char const *>("STR_ENABLE_CONTENT" "\004" u8"Allow updating"))); | ||||||||
505 | rBtn.connect_clicked(LINK(this, ScDocShell, ReloadAllLinksHdl)::tools::detail::makeLink( ::tools::detail::castTo<ScDocShell *>(this), &ScDocShell::LinkStubReloadAllLinksHdl)); | ||||||||
506 | } | ||||||||
507 | } | ||||||||
508 | rReq.Done(); | ||||||||
509 | } | ||||||||
510 | } | ||||||||
511 | break; | ||||||||
512 | |||||||||
513 | case SID_REIMPORT_AFTER_LOAD((26000) + 80): | ||||||||
514 | { | ||||||||
515 | // Is called after loading if there are DB areas with omitted data | ||||||||
516 | |||||||||
517 | bool bDone = false; | ||||||||
518 | ScDBCollection* pDBColl = m_aDocument.GetDBCollection(); | ||||||||
519 | |||||||||
520 | if ((m_nCanUpdate != css::document::UpdateDocMode::NO_UPDATE) && | ||||||||
521 | (m_nCanUpdate != css::document::UpdateDocMode::QUIET_UPDATE)) | ||||||||
522 | { | ||||||||
523 | ScRange aRange; | ||||||||
524 | ScTabViewShell* pViewSh = GetBestViewShell(); | ||||||||
525 | OSL_ENSURE(pViewSh,"SID_REIMPORT_AFTER_LOAD: no View")do { if (true && (!(pViewSh))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/ui/docshell/docsh4.cxx" ":" "525" ": "), "%s", "SID_REIMPORT_AFTER_LOAD: no View"); } } while (false); | ||||||||
526 | if (pViewSh && pDBColl) | ||||||||
527 | { | ||||||||
528 | std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(GetActiveDialogParent(), | ||||||||
529 | VclMessageType::Question, VclButtonsType::YesNo, | ||||||||
530 | ScResId(STR_REIMPORT_AFTER_LOADreinterpret_cast<char const *>("STR_REIMPORT_AFTER_LOAD" "\004" u8"This file contains queries. The results of these queries were not saved.\nDo you want these queries to be repeated?" )))); | ||||||||
531 | xQueryBox->set_default_response(RET_YES); | ||||||||
532 | if (xQueryBox->run() == RET_YES) | ||||||||
533 | { | ||||||||
534 | ScDBCollection::NamedDBs& rDBs = pDBColl->getNamedDBs(); | ||||||||
535 | for (const auto& rxDB : rDBs) | ||||||||
536 | { | ||||||||
537 | ScDBData& rDBData = *rxDB; | ||||||||
538 | if ( rDBData.IsStripData() && | ||||||||
539 | rDBData.HasImportParam() && !rDBData.HasImportSelection() ) | ||||||||
540 | { | ||||||||
541 | rDBData.GetArea(aRange); | ||||||||
542 | pViewSh->MarkRange(aRange); | ||||||||
543 | |||||||||
544 | // Import and internal operations like SID_REFRESH_DBAREA | ||||||||
545 | // (inquiry for import not needed here) | ||||||||
546 | |||||||||
547 | ScImportParam aImportParam; | ||||||||
548 | rDBData.GetImportParam( aImportParam ); | ||||||||
549 | bool bContinue = pViewSh->ImportData( aImportParam ); | ||||||||
550 | rDBData.SetImportParam( aImportParam ); | ||||||||
551 | |||||||||
552 | // mark (size may have changed) | ||||||||
553 | rDBData.GetArea(aRange); | ||||||||
554 | pViewSh->MarkRange(aRange); | ||||||||
555 | |||||||||
556 | if ( bContinue ) // error at import -> abort | ||||||||
557 | { | ||||||||
558 | // internal operations, if some where saved | ||||||||
559 | |||||||||
560 | if ( rDBData.HasQueryParam() || rDBData.HasSortParam() || | ||||||||
561 | rDBData.HasSubTotalParam() ) | ||||||||
562 | pViewSh->RepeatDB(); | ||||||||
563 | |||||||||
564 | // pivot tables, which have the range as source data | ||||||||
565 | |||||||||
566 | RefreshPivotTables(aRange); | ||||||||
567 | } | ||||||||
568 | } | ||||||||
569 | } | ||||||||
570 | bDone = true; | ||||||||
571 | } | ||||||||
572 | } | ||||||||
573 | } | ||||||||
574 | |||||||||
575 | if ( !bDone && pDBColl ) | ||||||||
576 | { | ||||||||
577 | // if not, but then update the dependent formulas | ||||||||
578 | //! also for individual ranges, which cannot be updated | ||||||||
579 | |||||||||
580 | m_aDocument.CalcAll(); //! only for the dependent | ||||||||
581 | PostDataChanged(); | ||||||||
582 | } | ||||||||
583 | |||||||||
584 | if (bDone) | ||||||||
585 | rReq.Done(); | ||||||||
586 | else | ||||||||
587 | rReq.Ignore(); | ||||||||
588 | } | ||||||||
589 | break; | ||||||||
590 | |||||||||
591 | case SID_AUTO_STYLE((26000 + 100) + 28): | ||||||||
592 | OSL_FAIL("use ScAutoStyleHint instead of SID_AUTO_STYLE")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/docsh4.cxx" ":" "592" ": "), "%s", "use ScAutoStyleHint instead of SID_AUTO_STYLE" ); } } while (false); | ||||||||
593 | break; | ||||||||
594 | |||||||||
595 | case SID_GET_COLORLIST( 10000 + 441 ): | ||||||||
596 | { | ||||||||
597 | const SvxColorListItem* pColItem = GetItem(SID_COLOR_TABLETypedWhichId<SvxColorListItem>( 10000 + 179 )); | ||||||||
598 | const XColorListRef& pList = pColItem->GetColorList(); | ||||||||
599 | rReq.SetReturnValue(OfaRefItem<XColorList>(SID_GET_COLORLIST( 10000 + 441 ), pList)); | ||||||||
600 | } | ||||||||
601 | break; | ||||||||
602 | |||||||||
603 | case FID_CHG_RECORD((((26000 + 200) + 20)) + 18): | ||||||||
604 | { | ||||||||
605 | ScDocument& rDoc = GetDocument(); | ||||||||
606 | // get argument (recorded macro) | ||||||||
607 | const SfxBoolItem* pItem = rReq.GetArg<SfxBoolItem>(FID_CHG_RECORD((((26000 + 200) + 20)) + 18)); | ||||||||
608 | bool bDo = true; | ||||||||
609 | |||||||||
610 | // desired state | ||||||||
611 | ScChangeTrack* pChangeTrack = rDoc.GetChangeTrack(); | ||||||||
612 | bool bActivateTracking = (pChangeTrack == nullptr); // toggle | ||||||||
613 | if ( pItem ) | ||||||||
614 | bActivateTracking = pItem->GetValue(); // from argument | ||||||||
615 | |||||||||
616 | if ( !bActivateTracking ) | ||||||||
617 | { | ||||||||
618 | if ( !pItem ) | ||||||||
619 | { | ||||||||
620 | // no dialog on playing the macro | ||||||||
621 | std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(GetActiveDialogParent(), | ||||||||
622 | VclMessageType::Warning, VclButtonsType::YesNo, | ||||||||
623 | ScResId(STR_END_REDLININGreinterpret_cast<char const *>("STR_END_REDLINING" "\004" u8"This action will exit the change recording mode.\nAny information about changes will be lost.\n\nExit change recording mode?\n\n" )))); | ||||||||
624 | xWarn->set_default_response(RET_NO); | ||||||||
625 | bDo = (xWarn->run() == RET_YES ); | ||||||||
626 | } | ||||||||
627 | |||||||||
628 | if ( bDo ) | ||||||||
629 | { | ||||||||
630 | if (pChangeTrack) | ||||||||
631 | { | ||||||||
632 | if ( pChangeTrack->IsProtected() ) | ||||||||
633 | bDo = ExecuteChangeProtectionDialog(); | ||||||||
634 | } | ||||||||
635 | if ( bDo ) | ||||||||
636 | { | ||||||||
637 | rDoc.EndChangeTracking(); | ||||||||
638 | PostPaintGridAll(); | ||||||||
639 | } | ||||||||
640 | } | ||||||||
641 | } | ||||||||
642 | else | ||||||||
643 | { | ||||||||
644 | rDoc.StartChangeTracking(); | ||||||||
645 | ScChangeViewSettings aChangeViewSet; | ||||||||
646 | aChangeViewSet.SetShowChanges(true); | ||||||||
647 | rDoc.SetChangeViewSettings(aChangeViewSet); | ||||||||
648 | } | ||||||||
649 | |||||||||
650 | if ( bDo ) | ||||||||
651 | { | ||||||||
652 | UpdateAcceptChangesDialog(); | ||||||||
653 | |||||||||
654 | // invalidate slots | ||||||||
655 | if (pBindings) | ||||||||
656 | pBindings->InvalidateAll(false); | ||||||||
657 | if ( !pItem ) | ||||||||
658 | rReq.AppendItem( SfxBoolItem( FID_CHG_RECORD((((26000 + 200) + 20)) + 18), bActivateTracking ) ); | ||||||||
659 | rReq.Done(); | ||||||||
660 | } | ||||||||
661 | else | ||||||||
662 | rReq.Ignore(); | ||||||||
663 | } | ||||||||
664 | break; | ||||||||
665 | |||||||||
666 | case SID_CHG_PROTECT((26000) + 84) : | ||||||||
667 | { | ||||||||
668 | if ( ExecuteChangeProtectionDialog() ) | ||||||||
669 | { | ||||||||
670 | rReq.Done(); | ||||||||
671 | SetDocumentModified(); | ||||||||
672 | } | ||||||||
673 | else | ||||||||
674 | rReq.Ignore(); | ||||||||
675 | } | ||||||||
676 | break; | ||||||||
677 | |||||||||
678 | case SID_DOCUMENT_MERGE(5000 + 1587): | ||||||||
679 | case SID_DOCUMENT_COMPARE(5000 + 1586): | ||||||||
680 | { | ||||||||
681 | bool bDo = true; | ||||||||
682 | ScChangeTrack* pChangeTrack = m_aDocument.GetChangeTrack(); | ||||||||
683 | if ( pChangeTrack && !m_pImpl->bIgnoreLostRedliningWarning ) | ||||||||
684 | { | ||||||||
685 | if ( nSlot == SID_DOCUMENT_COMPARE(5000 + 1586) ) | ||||||||
686 | { //! old changes trace will be lost | ||||||||
687 | std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(GetActiveDialogParent(), | ||||||||
688 | VclMessageType::Warning, VclButtonsType::YesNo, | ||||||||
689 | ScResId(STR_END_REDLININGreinterpret_cast<char const *>("STR_END_REDLINING" "\004" u8"This action will exit the change recording mode.\nAny information about changes will be lost.\n\nExit change recording mode?\n\n" )))); | ||||||||
690 | xWarn->set_default_response(RET_NO); | ||||||||
691 | if (xWarn->run() == RET_YES) | ||||||||
692 | bDo = ExecuteChangeProtectionDialog( true ); | ||||||||
693 | else | ||||||||
694 | bDo = false; | ||||||||
695 | } | ||||||||
696 | else // merge might reject some actions | ||||||||
697 | bDo = ExecuteChangeProtectionDialog( true ); | ||||||||
698 | } | ||||||||
699 | if ( !bDo ) | ||||||||
700 | { | ||||||||
701 | rReq.Ignore(); | ||||||||
702 | break; | ||||||||
703 | } | ||||||||
704 | SfxApplication* pApp = SfxGetpApp(); | ||||||||
705 | const SfxPoolItem* pItem; | ||||||||
706 | const SfxStringItem* pStringItem(nullptr); | ||||||||
707 | SfxMedium* pMed = nullptr; | ||||||||
708 | if (pReqArgs && pReqArgs->GetItemState(SID_FILE_NAME(5000 + 507), true, &pItem) == SfxItemState::SET) | ||||||||
709 | { | ||||||||
710 | pStringItem = dynamic_cast<const SfxStringItem*>(pItem); | ||||||||
711 | } | ||||||||
712 | if (pStringItem) | ||||||||
713 | { | ||||||||
714 | OUString aFileName = pStringItem->GetValue(); | ||||||||
715 | |||||||||
716 | OUString aFilterName; | ||||||||
717 | pStringItem = nullptr; | ||||||||
718 | if (pReqArgs->GetItemState(SID_FILTER_NAME(5000 + 530), true, &pItem) == SfxItemState::SET) | ||||||||
719 | pStringItem = dynamic_cast<const SfxStringItem*>(pItem); | ||||||||
720 | if (pStringItem) | ||||||||
721 | { | ||||||||
722 | aFilterName = pStringItem->GetValue(); | ||||||||
723 | } | ||||||||
724 | OUString aOptions; | ||||||||
725 | pStringItem = nullptr; | ||||||||
726 | if (pReqArgs->GetItemState(SID_FILE_FILTEROPTIONS(5000 + 527), true, &pItem) == SfxItemState::SET) | ||||||||
727 | pStringItem = dynamic_cast<const SfxStringItem*>(pItem); | ||||||||
728 | if (pStringItem) | ||||||||
729 | { | ||||||||
730 | aOptions = pStringItem->GetValue(); | ||||||||
731 | } | ||||||||
732 | short nVersion = 0; | ||||||||
733 | const SfxInt16Item* pInt16Item(nullptr); | ||||||||
734 | if (pReqArgs->GetItemState(SID_VERSION(5000 + 1583), true, &pItem) == SfxItemState::SET) | ||||||||
735 | pInt16Item = dynamic_cast<const SfxInt16Item*>(pItem); | ||||||||
736 | if (pInt16Item) | ||||||||
737 | { | ||||||||
738 | nVersion = pInt16Item->GetValue(); | ||||||||
739 | } | ||||||||
740 | |||||||||
741 | // no filter specified -> detection | ||||||||
742 | if (aFilterName.isEmpty()) | ||||||||
743 | ScDocumentLoader::GetFilterName( aFileName, aFilterName, aOptions, true, false ); | ||||||||
744 | |||||||||
745 | // filter name from dialog contains application prefix, | ||||||||
746 | // GetFilter needs name without the prefix. | ||||||||
747 | ScDocumentLoader::RemoveAppPrefix( aFilterName ); | ||||||||
748 | |||||||||
749 | std::shared_ptr<const SfxFilter> pFilter = ScDocShell::Factory().GetFilterContainer()->GetFilter4FilterName( aFilterName ); | ||||||||
750 | auto pSet = std::make_shared<SfxAllItemSet>( pApp->GetPool() ); | ||||||||
751 | if (!aOptions.isEmpty()) | ||||||||
752 | pSet->Put( SfxStringItem( SID_FILE_FILTEROPTIONS(5000 + 527), aOptions ) ); | ||||||||
753 | if ( nVersion != 0 ) | ||||||||
754 | pSet->Put( SfxInt16Item( SID_VERSION(5000 + 1583), nVersion ) ); | ||||||||
755 | pMed = new SfxMedium( aFileName, StreamMode::STD_READ, pFilter, std::move(pSet) ); | ||||||||
756 | } | ||||||||
757 | else | ||||||||
758 | { | ||||||||
759 | const sfx2::DocumentInserter::Mode mode { nSlot==SID_DOCUMENT_COMPARE(5000 + 1586) | ||||||||
760 | ? sfx2::DocumentInserter::Mode::Compare | ||||||||
761 | : sfx2::DocumentInserter::Mode::Merge}; | ||||||||
762 | // start file dialog asynchronous | ||||||||
763 | m_pImpl->bIgnoreLostRedliningWarning = true; | ||||||||
764 | m_pImpl->pRequest.reset(new SfxRequest( rReq )); | ||||||||
765 | m_pImpl->pDocInserter.reset(); | ||||||||
766 | |||||||||
767 | ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell(); | ||||||||
768 | weld::Window* pParent = pViewSh ? pViewSh->GetFrameWeld() : nullptr; | ||||||||
769 | m_pImpl->pDocInserter.reset( new ::sfx2::DocumentInserter(pParent, | ||||||||
770 | ScDocShell::Factory().GetFactoryName(), mode ) ); | ||||||||
771 | m_pImpl->pDocInserter->StartExecuteModal( LINK( this, ScDocShell, DialogClosedHdl )::tools::detail::makeLink( ::tools::detail::castTo<ScDocShell *>(this), &ScDocShell::LinkStubDialogClosedHdl) ); | ||||||||
772 | return ; | ||||||||
773 | } | ||||||||
774 | |||||||||
775 | // now execute in earnest... | ||||||||
776 | SfxErrorContext aEc( ERRCTX_SFX_OPENDOC51, pMed->GetName() ); | ||||||||
777 | |||||||||
778 | // pOtherDocSh->DoClose() will be called explicitly later, but it is still more safe to use SfxObjectShellLock here | ||||||||
779 | ScDocShell* pOtherDocSh = new ScDocShell; | ||||||||
780 | SfxObjectShellLock aDocShTablesRef = pOtherDocSh; | ||||||||
781 | pOtherDocSh->DoLoad( pMed ); | ||||||||
782 | ErrCode nErr = pOtherDocSh->GetErrorCode(); | ||||||||
783 | if (nErr) | ||||||||
784 | ErrorHandler::HandleError( nErr ); // also warnings | ||||||||
785 | |||||||||
786 | if ( !pOtherDocSh->GetError() ) // only errors | ||||||||
787 | { | ||||||||
788 | bool bHadTrack = ( m_aDocument.GetChangeTrack() != nullptr ); | ||||||||
789 | #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT1 | ||||||||
790 | sal_uLong nStart = 0; | ||||||||
791 | if ( nSlot == SID_DOCUMENT_MERGE(5000 + 1587) && pChangeTrack ) | ||||||||
792 | { | ||||||||
793 | nStart = pChangeTrack->GetActionMax() + 1; | ||||||||
794 | } | ||||||||
795 | #endif | ||||||||
796 | if ( nSlot == SID_DOCUMENT_COMPARE(5000 + 1586) ) | ||||||||
797 | CompareDocument( pOtherDocSh->GetDocument() ); | ||||||||
798 | else | ||||||||
799 | MergeDocument( pOtherDocSh->GetDocument() ); | ||||||||
800 | |||||||||
801 | // show "accept changes" dialog | ||||||||
802 | //! get view for this document! | ||||||||
803 | if ( !IsDocShared() ) | ||||||||
804 | { | ||||||||
805 | SfxViewFrame* pViewFrm = SfxViewFrame::Current(); | ||||||||
806 | if ( pViewFrm ) | ||||||||
807 | { | ||||||||
808 | pViewFrm->ShowChildWindow( ScAcceptChgDlgWrapper::GetChildWindowId() ); //@51669 | ||||||||
809 | } | ||||||||
810 | if ( pBindings ) | ||||||||
811 | { | ||||||||
812 | pBindings->Invalidate( FID_CHG_ACCEPT((((((26000 + 200) + 20)) + 20)) + 18) ); | ||||||||
813 | } | ||||||||
814 | } | ||||||||
815 | |||||||||
816 | rReq.SetReturnValue( SfxInt32Item( nSlot, 0 ) ); //! ??????? | ||||||||
817 | rReq.Done(); | ||||||||
818 | |||||||||
819 | if (!bHadTrack) // newly turned on -> show as well | ||||||||
820 | { | ||||||||
821 | ScChangeViewSettings* pOldSet = m_aDocument.GetChangeViewSettings(); | ||||||||
822 | if ( !pOldSet || !pOldSet->ShowChanges() ) | ||||||||
823 | { | ||||||||
824 | ScChangeViewSettings aChangeViewSet; | ||||||||
825 | aChangeViewSet.SetShowChanges(true); | ||||||||
826 | m_aDocument.SetChangeViewSettings(aChangeViewSet); | ||||||||
827 | } | ||||||||
828 | } | ||||||||
829 | #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT1 | ||||||||
830 | else if ( nSlot == SID_DOCUMENT_MERGE(5000 + 1587) && IsDocShared() && pChangeTrack ) | ||||||||
831 | { | ||||||||
832 | sal_uLong nEnd = pChangeTrack->GetActionMax(); | ||||||||
833 | if ( nEnd >= nStart ) | ||||||||
834 | { | ||||||||
835 | // only show changes from merged document | ||||||||
836 | ScChangeViewSettings aChangeViewSet; | ||||||||
837 | aChangeViewSet.SetShowChanges( true ); | ||||||||
838 | aChangeViewSet.SetShowAccepted( true ); | ||||||||
839 | aChangeViewSet.SetHasActionRange(); | ||||||||
840 | aChangeViewSet.SetTheActionRange( nStart, nEnd ); | ||||||||
841 | m_aDocument.SetChangeViewSettings( aChangeViewSet ); | ||||||||
842 | |||||||||
843 | // update view | ||||||||
844 | PostPaintExtras(); | ||||||||
845 | PostPaintGridAll(); | ||||||||
846 | } | ||||||||
847 | } | ||||||||
848 | #endif | ||||||||
849 | } | ||||||||
850 | pOtherDocSh->DoClose(); // delete happens with the Ref | ||||||||
851 | } | ||||||||
852 | break; | ||||||||
853 | |||||||||
854 | case SID_DELETE_SCENARIO((((26000 + 521) + 50))+95): | ||||||||
855 | if (pReqArgs) | ||||||||
856 | { | ||||||||
857 | const SfxPoolItem* pItem; | ||||||||
858 | if ( pReqArgs->GetItemState( nSlot, true, &pItem ) == SfxItemState::SET ) | ||||||||
859 | { | ||||||||
860 | if (const SfxStringItem* pStringItem = dynamic_cast<const SfxStringItem*>(pItem)) | ||||||||
861 | { | ||||||||
862 | const OUString& aName = pStringItem->GetValue(); | ||||||||
863 | SCTAB nTab; | ||||||||
864 | if (m_aDocument.GetTable( aName, nTab )) | ||||||||
865 | { | ||||||||
866 | // move DeleteTable from viewfunc to docfunc! | ||||||||
867 | |||||||||
868 | ScTabViewShell* pSh = GetBestViewShell(); | ||||||||
869 | if ( pSh ) | ||||||||
870 | { | ||||||||
871 | //! omit SetTabNo in DeleteTable? | ||||||||
872 | SCTAB nDispTab = pSh->GetViewData().GetTabNo(); | ||||||||
873 | pSh->DeleteTable( nTab ); | ||||||||
874 | pSh->SetTabNo(nDispTab); | ||||||||
875 | rReq.Done(); | ||||||||
876 | } | ||||||||
877 | } | ||||||||
878 | } | ||||||||
879 | } | ||||||||
880 | } | ||||||||
881 | break; | ||||||||
882 | |||||||||
883 | case SID_EDIT_SCENARIO((((26000 + 521) + 50))+96): | ||||||||
884 | { | ||||||||
885 | const SfxPoolItem* pItem; | ||||||||
886 | if ( pReqArgs->GetItemState( nSlot, true, &pItem ) == SfxItemState::SET ) | ||||||||
887 | { | ||||||||
888 | if (const SfxStringItem* pStringItem = dynamic_cast<const SfxStringItem*>(pItem)) | ||||||||
889 | { | ||||||||
890 | OUString aName = pStringItem->GetValue(); | ||||||||
891 | SCTAB nTab; | ||||||||
892 | if (m_aDocument.GetTable( aName, nTab )) | ||||||||
893 | { | ||||||||
894 | if (m_aDocument.IsScenario(nTab)) | ||||||||
895 | { | ||||||||
896 | OUString aComment; | ||||||||
897 | Color aColor; | ||||||||
898 | ScScenarioFlags nFlags; | ||||||||
899 | m_aDocument.GetScenarioData( nTab, aComment, aColor, nFlags ); | ||||||||
900 | |||||||||
901 | // Determine if the Sheet that the Scenario was created on | ||||||||
902 | // is protected. But first we need to find that Sheet. | ||||||||
903 | // Rewind back to the actual sheet. | ||||||||
904 | SCTAB nActualTab = nTab; | ||||||||
905 | do | ||||||||
906 | { | ||||||||
907 | nActualTab--; | ||||||||
908 | } | ||||||||
909 | while(m_aDocument.IsScenario(nActualTab)); | ||||||||
910 | bool bSheetProtected = m_aDocument.IsTabProtected(nActualTab); | ||||||||
911 | |||||||||
912 | ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create(); | ||||||||
913 | |||||||||
914 | ScopedVclPtr<AbstractScNewScenarioDlg> pNewDlg(pFact->CreateScNewScenarioDlg(GetActiveDialogParent(), aName, true, bSheetProtected)); | ||||||||
915 | pNewDlg->SetScenarioData( aName, aComment, aColor, nFlags ); | ||||||||
916 | if ( pNewDlg->Execute() == RET_OK ) | ||||||||
917 | { | ||||||||
918 | pNewDlg->GetScenarioData( aName, aComment, aColor, nFlags ); | ||||||||
919 | ModifyScenario( nTab, aName, aComment, aColor, nFlags ); | ||||||||
920 | rReq.Done(); | ||||||||
921 | } | ||||||||
922 | } | ||||||||
923 | } | ||||||||
924 | } | ||||||||
925 | } | ||||||||
926 | } | ||||||||
927 | break; | ||||||||
928 | |||||||||
929 | case SID_ATTR_YEAR2000(((((10000 + 1499) + 1) + 499) + 1) + 87) : | ||||||||
930 | { | ||||||||
931 | const SfxPoolItem* pItem; | ||||||||
932 | if ( pReqArgs->GetItemState( nSlot, true, &pItem ) == SfxItemState::SET ) | ||||||||
933 | { | ||||||||
934 | if (const SfxUInt16Item* pInt16Item = dynamic_cast<const SfxUInt16Item*>(pItem)) | ||||||||
935 | { | ||||||||
936 | sal_uInt16 nY2k = pInt16Item->GetValue(); | ||||||||
937 | // set always to DocOptions, so that it is also saved for S050 | ||||||||
938 | // (and all inquiries run up until now on it as well). | ||||||||
939 | // SetDocOptions propagates that to the NumberFormatter | ||||||||
940 | ScDocOptions aDocOpt( m_aDocument.GetDocOptions() ); | ||||||||
941 | aDocOpt.SetYear2000( nY2k ); | ||||||||
942 | m_aDocument.SetDocOptions( aDocOpt ); | ||||||||
943 | // the FormShell shall notice it as well | ||||||||
944 | ScTabViewShell* pSh = GetBestViewShell(); | ||||||||
945 | if ( pSh ) | ||||||||
946 | { | ||||||||
947 | FmFormShell* pFSh = pSh->GetFormShell(); | ||||||||
948 | if ( pFSh ) | ||||||||
949 | pFSh->SetY2KState( nY2k ); | ||||||||
950 | } | ||||||||
951 | } | ||||||||
952 | } | ||||||||
953 | } | ||||||||
954 | break; | ||||||||
955 | |||||||||
956 | #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT1 | ||||||||
957 | case SID_SHARE_DOC((((((((((((26000 + 200) + 20)) + 20)) + 20)) + 25)) + 22)) + 11): | ||||||||
958 | { | ||||||||
959 | ScViewData* pViewData = GetViewData(); | ||||||||
960 | if ( !pViewData ) | ||||||||
961 | { | ||||||||
962 | rReq.Ignore(); | ||||||||
963 | break; | ||||||||
964 | } | ||||||||
965 | |||||||||
966 | weld::Window* pWin = GetActiveDialogParent(); | ||||||||
967 | ScShareDocumentDlg aDlg(pWin, pViewData); | ||||||||
968 | if (aDlg.run() == RET_OK) | ||||||||
969 | { | ||||||||
970 | bool bSetShared = aDlg.IsShareDocumentChecked(); | ||||||||
971 | if ( bSetShared != IsDocShared() ) | ||||||||
972 | { | ||||||||
973 | if ( bSetShared ) | ||||||||
974 | { | ||||||||
975 | bool bContinue = true; | ||||||||
976 | if ( HasName() ) | ||||||||
977 | { | ||||||||
978 | std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(pWin, | ||||||||
979 | VclMessageType::Question, VclButtonsType::YesNo, | ||||||||
980 | ScResId(STR_DOC_WILLBESAVEDreinterpret_cast<char const *>("STR_DOC_WILLBESAVED" "\004" u8"The spreadsheet must be saved now to activate sharing mode.\n\nDo you want to continue?" )))); | ||||||||
981 | xQueryBox->set_default_response(RET_YES); | ||||||||
982 | if (xQueryBox->run() == RET_NO) | ||||||||
983 | { | ||||||||
984 | bContinue = false; | ||||||||
985 | } | ||||||||
986 | } | ||||||||
987 | if ( bContinue ) | ||||||||
988 | { | ||||||||
989 | EnableSharedSettings( true ); | ||||||||
990 | |||||||||
991 | SC_MOD()( static_cast<ScModule*>(SfxApplication::GetModule(SfxToolsModule ::Calc)) )->SetInSharedDocSaving( true ); | ||||||||
992 | if ( !SwitchToShared( true, true ) ) | ||||||||
993 | { | ||||||||
994 | // TODO/LATER: what should be done in case the switch has failed? | ||||||||
995 | // for example in case the user has cancelled the saveAs operation | ||||||||
996 | } | ||||||||
997 | |||||||||
998 | SC_MOD()( static_cast<ScModule*>(SfxApplication::GetModule(SfxToolsModule ::Calc)) )->SetInSharedDocSaving( false ); | ||||||||
999 | |||||||||
1000 | InvalidateName(); | ||||||||
1001 | GetUndoManager()->Clear(); | ||||||||
1002 | |||||||||
1003 | ScTabView* pTabView = dynamic_cast< ScTabView* >( pViewData->GetView() ); | ||||||||
1004 | if ( pTabView ) | ||||||||
1005 | { | ||||||||
1006 | pTabView->UpdateLayerLocks(); | ||||||||
1007 | } | ||||||||
1008 | } | ||||||||
1009 | } | ||||||||
1010 | else | ||||||||
1011 | { | ||||||||
1012 | uno::Reference< frame::XModel > xModel; | ||||||||
1013 | try | ||||||||
1014 | { | ||||||||
1015 | // load shared file | ||||||||
1016 | xModel.set( LoadSharedDocument(), uno::UNO_SET_THROW ); | ||||||||
1017 | uno::Reference< util::XCloseable > xCloseable( xModel, uno::UNO_QUERY_THROW ); | ||||||||
1018 | |||||||||
1019 | // check if shared flag is set in shared file | ||||||||
1020 | bool bShared = false; | ||||||||
1021 | ScModelObj* pDocObj = comphelper::getUnoTunnelImplementation<ScModelObj>( xModel ); | ||||||||
1022 | if ( pDocObj ) | ||||||||
1023 | { | ||||||||
1024 | ScDocShell* pDocShell = dynamic_cast< ScDocShell* >( pDocObj->GetEmbeddedObject() ); | ||||||||
1025 | if ( pDocShell ) | ||||||||
1026 | { | ||||||||
1027 | bShared = pDocShell->HasSharedXMLFlagSet(); | ||||||||
1028 | } | ||||||||
1029 | } | ||||||||
1030 | |||||||||
1031 | // #i87870# check if shared status was disabled and enabled again | ||||||||
1032 | bool bOwnEntry = false; | ||||||||
1033 | try | ||||||||
1034 | { | ||||||||
1035 | ::svt::ShareControlFile aControlFile( GetSharedFileURL() ); | ||||||||
1036 | bOwnEntry = aControlFile.HasOwnEntry(); | ||||||||
1037 | } | ||||||||
1038 | catch ( uno::Exception& ) | ||||||||
1039 | { | ||||||||
1040 | } | ||||||||
1041 | |||||||||
1042 | if ( bShared && bOwnEntry ) | ||||||||
1043 | { | ||||||||
1044 | uno::Reference< frame::XStorable > xStorable( xModel, uno::UNO_QUERY_THROW ); | ||||||||
1045 | if ( xStorable->isReadonly() ) | ||||||||
1046 | { | ||||||||
1047 | xCloseable->close( true ); | ||||||||
1048 | |||||||||
1049 | OUString aUserName( ScResId( STR_UNKNOWN_USERreinterpret_cast<char const *>("STR_UNKNOWN_USER" "\004" u8"Unknown User") ) ); | ||||||||
1050 | try | ||||||||
1051 | { | ||||||||
1052 | ::svt::DocumentLockFile aLockFile( GetSharedFileURL() ); | ||||||||
1053 | LockFileEntry aData = aLockFile.GetLockData(); | ||||||||
1054 | if ( !aData[LockFileComponent::OOOUSERNAME].isEmpty() ) | ||||||||
1055 | { | ||||||||
1056 | aUserName = aData[LockFileComponent::OOOUSERNAME]; | ||||||||
1057 | } | ||||||||
1058 | else if ( !aData[LockFileComponent::SYSUSERNAME].isEmpty() ) | ||||||||
1059 | { | ||||||||
1060 | aUserName = aData[LockFileComponent::SYSUSERNAME]; | ||||||||
1061 | } | ||||||||
1062 | } | ||||||||
1063 | catch ( uno::Exception& ) | ||||||||
1064 | { | ||||||||
1065 | } | ||||||||
1066 | OUString aMessage( ScResId( STR_FILE_LOCKED_TRY_LATERreinterpret_cast<char const *>("STR_FILE_LOCKED_TRY_LATER" "\004" u8"The shared spreadsheet file is locked due to a merge in progress by user: '%1'\n\nSharing mode of a locked file cannot be disabled. Try again later." ) ) ); | ||||||||
1067 | aMessage = aMessage.replaceFirst( "%1", aUserName ); | ||||||||
1068 | |||||||||
1069 | std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(pWin, | ||||||||
1070 | VclMessageType::Warning, VclButtonsType::Ok, | ||||||||
1071 | aMessage)); | ||||||||
1072 | xWarn->run(); | ||||||||
1073 | } | ||||||||
1074 | else | ||||||||
1075 | { | ||||||||
1076 | std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(pWin, | ||||||||
1077 | VclMessageType::Warning, VclButtonsType::YesNo, | ||||||||
1078 | ScResId(STR_DOC_DISABLESHAREDreinterpret_cast<char const *>("STR_DOC_DISABLESHARED" "\004" u8"Disabling shared mode of a spreadsheet hinders all other users of the shared spreadsheet to merge back their work.\n\nDo you want to continue?" )))); | ||||||||
1079 | xWarn->set_default_response(RET_YES); | ||||||||
1080 | |||||||||
1081 | if (xWarn->run() == RET_YES) | ||||||||
1082 | { | ||||||||
1083 | xCloseable->close( true ); | ||||||||
1084 | |||||||||
1085 | if ( !SwitchToShared( false, true ) ) | ||||||||
1086 | { | ||||||||
1087 | // TODO/LATER: what should be done in case the switch has failed? | ||||||||
1088 | // for example in case the user has cancelled the saveAs operation | ||||||||
1089 | } | ||||||||
1090 | |||||||||
1091 | EnableSharedSettings( false ); | ||||||||
1092 | |||||||||
1093 | if ( pBindings ) | ||||||||
1094 | { | ||||||||
1095 | pBindings->ExecuteSynchron( SID_SAVEDOC(5000 + 505) ); | ||||||||
1096 | } | ||||||||
1097 | |||||||||
1098 | ScTabView* pTabView = dynamic_cast< ScTabView* >( pViewData->GetView() ); | ||||||||
1099 | if ( pTabView ) | ||||||||
1100 | { | ||||||||
1101 | pTabView->UpdateLayerLocks(); | ||||||||
1102 | } | ||||||||
1103 | } | ||||||||
1104 | else | ||||||||
1105 | { | ||||||||
1106 | xCloseable->close( true ); | ||||||||
1107 | } | ||||||||
1108 | } | ||||||||
1109 | } | ||||||||
1110 | else | ||||||||
1111 | { | ||||||||
1112 | xCloseable->close( true ); | ||||||||
1113 | std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(pWin, | ||||||||
1114 | VclMessageType::Warning, VclButtonsType::Ok, | ||||||||
1115 | 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." )))); | ||||||||
1116 | xWarn->run(); | ||||||||
1117 | } | ||||||||
1118 | } | ||||||||
1119 | catch ( uno::Exception& ) | ||||||||
1120 | { | ||||||||
1121 | OSL_FAIL( "SID_SHARE_DOC: 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/docsh4.cxx" ":" "1121" ": "), "%s", "SID_SHARE_DOC: caught exception"); } } while (false); | ||||||||
1122 | SC_MOD()( static_cast<ScModule*>(SfxApplication::GetModule(SfxToolsModule ::Calc)) )->SetInSharedDocSaving( false ); | ||||||||
1123 | |||||||||
1124 | try | ||||||||
1125 | { | ||||||||
1126 | uno::Reference< util::XCloseable > xClose( xModel, uno::UNO_QUERY_THROW ); | ||||||||
1127 | xClose->close( true ); | ||||||||
1128 | } | ||||||||
1129 | catch ( uno::Exception& ) | ||||||||
1130 | { | ||||||||
1131 | } | ||||||||
1132 | } | ||||||||
1133 | } | ||||||||
1134 | } | ||||||||
1135 | } | ||||||||
1136 | rReq.Done(); | ||||||||
1137 | } | ||||||||
1138 | break; | ||||||||
1139 | #endif | ||||||||
1140 | case SID_OPEN_CALC((26000 + 200) + 4): | ||||||||
1141 | { | ||||||||
1142 | SfxStringItem aApp(SID_DOC_SERVICE(5000 + 511), "com.sun.star.sheet.SpreadsheetDocument"); | ||||||||
1143 | SfxStringItem aTarget(SID_TARGETNAME(5000 + 560), "_blank"); | ||||||||
1144 | GetViewData()->GetDispatcher().ExecuteList( | ||||||||
1145 | SID_OPENDOC(5000 + 501), SfxCallMode::API|SfxCallMode::SYNCHRON, | ||||||||
1146 | { &aApp, &aTarget }); | ||||||||
1147 | } | ||||||||
1148 | break; | ||||||||
1149 | case SID_NOTEBOOKBAR(10000 + 338): | ||||||||
1150 | { | ||||||||
1151 | const SfxStringItem* pFile = rReq.GetArg<SfxStringItem>( SID_NOTEBOOKBAR(10000 + 338) ); | ||||||||
1152 | |||||||||
1153 | if ( pBindings && sfx2::SfxNotebookBar::IsActive() ) | ||||||||
1154 | sfx2::SfxNotebookBar::ExecMethod(*pBindings, pFile ? pFile->GetValue() : ""); | ||||||||
1155 | else if ( pBindings ) | ||||||||
1156 | sfx2::SfxNotebookBar::CloseMethod(*pBindings); | ||||||||
1157 | } | ||||||||
1158 | break; | ||||||||
1159 | case SID_LANGUAGE_STATUS( 10000 + 1067 ): | ||||||||
1160 | { | ||||||||
1161 | OUString aLangText; | ||||||||
1162 | const SfxStringItem* pItem = rReq.GetArg<SfxStringItem>(nSlot); | ||||||||
1163 | if ( pItem
| ||||||||
1164 | aLangText = pItem->GetValue(); | ||||||||
1165 | |||||||||
1166 | if ( !aLangText.isEmpty() ) | ||||||||
1167 | { | ||||||||
1168 | LanguageType eLang, eLatin, eCjk, eCtl; | ||||||||
1169 | const OUString aSelectionLangPrefix("Current_"); | ||||||||
1170 | const OUString aParagraphLangPrefix("Paragraph_"); | ||||||||
1171 | const OUString aDocLangPrefix("Default_"); | ||||||||
1172 | |||||||||
1173 | bool bSelection = false; | ||||||||
1174 | bool bParagraph = false; | ||||||||
1175 | |||||||||
1176 | ScDocument& rDoc = GetDocument(); | ||||||||
1177 | rDoc.GetLanguage( eLatin, eCjk, eCtl ); | ||||||||
1178 | |||||||||
1179 | sal_Int32 nPos = 0; | ||||||||
1180 | if ( aLangText == "*" ) | ||||||||
1181 | { | ||||||||
1182 | SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create(); | ||||||||
1183 | ScTabViewShell* pSh = GetBestViewShell(); | ||||||||
1184 | ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateVclDialog(pSh
| ||||||||
1185 | pDlg->Execute(); | ||||||||
1186 | |||||||||
1187 | rDoc.GetLanguage( eLang, eCjk, eCtl ); | ||||||||
1188 | } | ||||||||
1189 | else if ( (nPos = aLangText.indexOf(aDocLangPrefix)) != -1 ) | ||||||||
1190 | { | ||||||||
1191 | aLangText = aLangText.replaceAt(nPos, aDocLangPrefix.getLength(), ""); | ||||||||
1192 | |||||||||
1193 | if ( aLangText == "LANGUAGE_NONE" ) | ||||||||
1194 | { | ||||||||
1195 | eLang = LANGUAGE_NONELanguageType(0x00FF); | ||||||||
1196 | rDoc.SetLanguage( eLang, eCjk, eCtl ); | ||||||||
1197 | } | ||||||||
1198 | else if ( aLangText == "RESET_LANGUAGES" ) | ||||||||
1199 | { | ||||||||
1200 | bool bAutoSpell; | ||||||||
1201 | |||||||||
1202 | ScModule::GetSpellSettings(eLang, eCjk, eCtl, bAutoSpell); | ||||||||
1203 | rDoc.SetLanguage(eLang, eCjk, eCtl); | ||||||||
1204 | } | ||||||||
1205 | else | ||||||||
1206 | { | ||||||||
1207 | eLang = SvtLanguageTable::GetLanguageType( aLangText ); | ||||||||
1208 | if ( eLang != LANGUAGE_DONTKNOWLanguageType(0x03FF) && SvtLanguageOptions::GetScriptTypeOfLanguage(eLang) == SvtScriptType::LATIN ) | ||||||||
1209 | { | ||||||||
1210 | rDoc.SetLanguage( eLang, eCjk, eCtl ); | ||||||||
1211 | } | ||||||||
1212 | else | ||||||||
1213 | { | ||||||||
1214 | eLang = eLatin; | ||||||||
1215 | } | ||||||||
1216 | } | ||||||||
1217 | } | ||||||||
1218 | else if (-1 != (nPos = aLangText.indexOf( aSelectionLangPrefix ))) | ||||||||
1219 | { | ||||||||
1220 | bSelection = true; | ||||||||
1221 | aLangText = aLangText.replaceAt( nPos, aSelectionLangPrefix.getLength(), "" ); | ||||||||
1222 | } | ||||||||
1223 | else if (-1 != (nPos = aLangText.indexOf( aParagraphLangPrefix ))) | ||||||||
1224 | { | ||||||||
1225 | bParagraph = true; | ||||||||
1226 | aLangText = aLangText.replaceAt( nPos, aParagraphLangPrefix.getLength(), "" ); | ||||||||
1227 | } | ||||||||
1228 | |||||||||
1229 | if (bSelection || bParagraph) | ||||||||
1230 | { | ||||||||
1231 | ScViewData* pViewData = GetViewData(); | ||||||||
1232 | if (!pViewData) | ||||||||
1233 | return; | ||||||||
1234 | |||||||||
1235 | EditView* pEditView = pViewData->GetEditView(pViewData->GetActivePart()); | ||||||||
1236 | if (!pEditView) | ||||||||
1237 | return; | ||||||||
1238 | |||||||||
1239 | const LanguageType nLangToUse = SvtLanguageTable::GetLanguageType( aLangText ); | ||||||||
1240 | SvtScriptType nScriptType = SvtLanguageOptions::GetScriptTypeOfLanguage( nLangToUse ); | ||||||||
1241 | |||||||||
1242 | SfxItemSet aAttrs = pEditView->GetEditEngine()->GetEmptyItemSet(); | ||||||||
1243 | if (nScriptType == SvtScriptType::LATIN) | ||||||||
1244 | aAttrs.Put( SvxLanguageItem( nLangToUse, EE_CHAR_LANGUAGE ) ); | ||||||||
1245 | if (nScriptType == SvtScriptType::COMPLEX) | ||||||||
1246 | aAttrs.Put( SvxLanguageItem( nLangToUse, EE_CHAR_LANGUAGE_CTL ) ); | ||||||||
1247 | if (nScriptType == SvtScriptType::ASIAN) | ||||||||
1248 | aAttrs.Put( SvxLanguageItem( nLangToUse, EE_CHAR_LANGUAGE_CJK ) ); | ||||||||
1249 | ESelection aOldSel; | ||||||||
1250 | if (bParagraph) | ||||||||
1251 | { | ||||||||
1252 | ESelection aSel = pEditView->GetSelection(); | ||||||||
1253 | aOldSel = aSel; | ||||||||
1254 | aSel.nStartPos = 0; | ||||||||
1255 | aSel.nEndPos = EE_TEXTPOS_ALL((sal_Int32) 0x7FFFFFFF); | ||||||||
1256 | pEditView->SetSelection( aSel ); | ||||||||
1257 | } | ||||||||
1258 | |||||||||
1259 | pEditView->SetAttribs( aAttrs ); | ||||||||
1260 | if (bParagraph) | ||||||||
1261 | pEditView->SetSelection( aOldSel ); | ||||||||
1262 | } | ||||||||
1263 | else if ( eLang != eLatin ) | ||||||||
1264 | { | ||||||||
1265 | if ( ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell() ) | ||||||||
1266 | { | ||||||||
1267 | ScInputHandler* pInputHandler = SC_MOD()( static_cast<ScModule*>(SfxApplication::GetModule(SfxToolsModule ::Calc)) )->GetInputHdl(pViewSh); | ||||||||
1268 | if ( pInputHandler ) | ||||||||
1269 | pInputHandler->UpdateSpellSettings(); | ||||||||
1270 | |||||||||
1271 | pViewSh->UpdateDrawTextOutliner(); | ||||||||
1272 | } | ||||||||
1273 | |||||||||
1274 | SetDocumentModified(); | ||||||||
1275 | Broadcast(SfxHint(SfxHintId::LanguageChanged)); | ||||||||
1276 | PostPaintGridAll(); | ||||||||
1277 | } | ||||||||
1278 | } | ||||||||
1279 | } | ||||||||
1280 | break; | ||||||||
1281 | case SID_SPELLCHECK_IGNORE_ALL( 10000 + 247 ): | ||||||||
1282 | { | ||||||||
1283 | ScViewData* pViewData = GetViewData(); | ||||||||
1284 | if (!pViewData) | ||||||||
1285 | return; | ||||||||
1286 | |||||||||
1287 | EditView* pEditView = pViewData->GetEditView(pViewData->GetActivePart()); | ||||||||
1288 | if (!pEditView) | ||||||||
1289 | return; | ||||||||
1290 | |||||||||
1291 | OUString sIgnoreText; | ||||||||
1292 | const SfxStringItem* pItem2 = rReq.GetArg<SfxStringItem>(FN_PARAM_1((20000 + 1100)+60)); | ||||||||
1293 | if (pItem2) | ||||||||
1294 | sIgnoreText = pItem2->GetValue(); | ||||||||
1295 | |||||||||
1296 | if(sIgnoreText == "Spelling") | ||||||||
1297 | { | ||||||||
1298 | ESelection aOldSel = pEditView->GetSelection(); | ||||||||
1299 | pEditView->SpellIgnoreWord(); | ||||||||
1300 | pEditView->SetSelection( aOldSel ); | ||||||||
1301 | } | ||||||||
1302 | } | ||||||||
1303 | break; | ||||||||
1304 | case SID_SPELLCHECK_APPLY_SUGGESTION( 10000 + 248 ): | ||||||||
1305 | { | ||||||||
1306 | ScViewData* pViewData = GetViewData(); | ||||||||
1307 | if (!pViewData) | ||||||||
1308 | return; | ||||||||
1309 | |||||||||
1310 | EditView* pEditView = pViewData->GetEditView(pViewData->GetActivePart()); | ||||||||
1311 | if (!pEditView) | ||||||||
1312 | return; | ||||||||
1313 | |||||||||
1314 | OUString sApplyText; | ||||||||
1315 | const SfxStringItem* pItem2 = rReq.GetArg<SfxStringItem>(FN_PARAM_1((20000 + 1100)+60)); | ||||||||
1316 | if (pItem2) | ||||||||
1317 | sApplyText = pItem2->GetValue(); | ||||||||
1318 | |||||||||
1319 | const OUString sSpellingRule("Spelling_"); | ||||||||
1320 | sal_Int32 nPos = 0; | ||||||||
1321 | if(-1 != (nPos = sApplyText.indexOf( sSpellingRule ))) | ||||||||
1322 | { | ||||||||
1323 | sApplyText = sApplyText.replaceAt(nPos, sSpellingRule.getLength(), ""); | ||||||||
1324 | pEditView->InsertText( sApplyText ); | ||||||||
1325 | } | ||||||||
1326 | } | ||||||||
1327 | break; | ||||||||
1328 | default: | ||||||||
1329 | { | ||||||||
1330 | // small (?) hack -> forwarding of the slots to TabViewShell | ||||||||
1331 | ScTabViewShell* pSh = GetBestViewShell(); | ||||||||
1332 | if ( pSh ) | ||||||||
1333 | pSh->Execute( rReq ); | ||||||||
1334 | #if HAVE_FEATURE_SCRIPTING1 | ||||||||
1335 | else | ||||||||
1336 | SbxBase::SetError( ERRCODE_BASIC_NO_ACTIVE_OBJECTErrCode( ErrCodeArea::Sbx, ErrCodeClass::Access, 13) ); | ||||||||
1337 | #endif | ||||||||
1338 | } | ||||||||
1339 | } | ||||||||
1340 | } | ||||||||
1341 | |||||||||
1342 | void UpdateAcceptChangesDialog() | ||||||||
1343 | { | ||||||||
1344 | // update "accept changes" dialog | ||||||||
1345 | //! notify all views | ||||||||
1346 | SfxViewFrame* pViewFrm = SfxViewFrame::Current(); | ||||||||
1347 | if ( pViewFrm && pViewFrm->HasChildWindow( FID_CHG_ACCEPT((((((26000 + 200) + 20)) + 20)) + 18) ) ) | ||||||||
1348 | { | ||||||||
1349 | SfxChildWindow* pChild = pViewFrm->GetChildWindow( FID_CHG_ACCEPT((((((26000 + 200) + 20)) + 20)) + 18) ); | ||||||||
1350 | if ( pChild ) | ||||||||
1351 | static_cast<ScAcceptChgDlgWrapper*>(pChild)->ReInitDlg(); | ||||||||
1352 | } | ||||||||
1353 | } | ||||||||
1354 | |||||||||
1355 | bool ScDocShell::ExecuteChangeProtectionDialog( bool bJustQueryIfProtected ) | ||||||||
1356 | { | ||||||||
1357 | bool bDone = false; | ||||||||
1358 | ScChangeTrack* pChangeTrack = m_aDocument.GetChangeTrack(); | ||||||||
1359 | if ( pChangeTrack ) | ||||||||
1360 | { | ||||||||
1361 | bool bProtected = pChangeTrack->IsProtected(); | ||||||||
1362 | if ( bJustQueryIfProtected && !bProtected ) | ||||||||
1363 | return true; | ||||||||
1364 | |||||||||
1365 | OUString aTitle( ScResId( bProtected ? SCSTR_CHG_UNPROTECTreinterpret_cast<char const *>("SCSTR_CHG_UNPROTECT" "\004" u8"Unprotect Records") : SCSTR_CHG_PROTECTreinterpret_cast<char const *>("SCSTR_CHG_PROTECT" "\004" u8"Protect Records") ) ); | ||||||||
1366 | OUString aText( ScResId( SCSTR_PASSWORDreinterpret_cast<char const *>("SCSTR_PASSWORD" "\004" u8"Password:" ) ) ); | ||||||||
1367 | OUString aPassword; | ||||||||
1368 | |||||||||
1369 | weld::Window* pWin = ScDocShell::GetActiveDialogParent(); | ||||||||
1370 | SfxPasswordDialog aDlg(pWin, &aText); | ||||||||
1371 | aDlg.set_title(aTitle); | ||||||||
1372 | aDlg.SetMinLen(1); | ||||||||
1373 | aDlg.set_help_id(GetStaticInterface()->GetSlot(SID_CHG_PROTECT((26000) + 84))->GetCommand()); | ||||||||
1374 | aDlg.SetEditHelpId( HID_CHG_PROTECT"SC_HID_CHG_PROTECT" ); | ||||||||
1375 | if ( !bProtected ) | ||||||||
1376 | aDlg.ShowExtras(SfxShowExtras::CONFIRM); | ||||||||
1377 | if (aDlg.run() == RET_OK) | ||||||||
1378 | aPassword = aDlg.GetPassword(); | ||||||||
1379 | |||||||||
1380 | if (!aPassword.isEmpty()) | ||||||||
1381 | { | ||||||||
1382 | if ( bProtected ) | ||||||||
1383 | { | ||||||||
1384 | if ( SvPasswordHelper::CompareHashPassword(pChangeTrack->GetProtection(), aPassword) ) | ||||||||
1385 | { | ||||||||
1386 | if ( bJustQueryIfProtected ) | ||||||||
1387 | bDone = true; | ||||||||
1388 | else | ||||||||
1389 | pChangeTrack->SetProtection( | ||||||||
1390 | css::uno::Sequence< sal_Int8 > (0) ); | ||||||||
1391 | } | ||||||||
1392 | else | ||||||||
1393 | { | ||||||||
1394 | std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(pWin, | ||||||||
1395 | VclMessageType::Info, VclButtonsType::Ok, | ||||||||
1396 | ScResId(SCSTR_WRONGPASSWORDreinterpret_cast<char const *>("SCSTR_WRONGPASSWORD" "\004" u8"Incorrect Password")))); | ||||||||
1397 | xInfoBox->run(); | ||||||||
1398 | } | ||||||||
1399 | } | ||||||||
1400 | else | ||||||||
1401 | { | ||||||||
1402 | css::uno::Sequence< sal_Int8 > aPass; | ||||||||
1403 | SvPasswordHelper::GetHashPassword( aPass, aPassword ); | ||||||||
1404 | pChangeTrack->SetProtection( aPass ); | ||||||||
1405 | } | ||||||||
1406 | if ( bProtected != pChangeTrack->IsProtected() ) | ||||||||
1407 | { | ||||||||
1408 | UpdateAcceptChangesDialog(); | ||||||||
1409 | bDone = true; | ||||||||
1410 | } | ||||||||
1411 | } | ||||||||
1412 | } | ||||||||
1413 | else if ( bJustQueryIfProtected ) | ||||||||
1414 | bDone = true; | ||||||||
1415 | return bDone; | ||||||||
1416 | } | ||||||||
1417 | |||||||||
1418 | void ScDocShell::DoRecalc( bool bApi ) | ||||||||
1419 | { | ||||||||
1420 | ScDocShellRecalcGuard aGuard(m_aDocument); | ||||||||
1421 | bool bDone = false; | ||||||||
1422 | ScTabViewShell* pSh = GetBestViewShell(); | ||||||||
1423 | ScInputHandler* pHdl = ( pSh ? SC_MOD()( static_cast<ScModule*>(SfxApplication::GetModule(SfxToolsModule ::Calc)) )->GetInputHdl( pSh ) : nullptr ); | ||||||||
1424 | if ( pSh ) | ||||||||
1425 | { | ||||||||
1426 | if ( pHdl && pHdl->IsInputMode() && pHdl->IsFormulaMode() && !bApi ) | ||||||||
1427 | { | ||||||||
1428 | pHdl->FormulaPreview(); // partial result as QuickHelp | ||||||||
1429 | bDone = true; | ||||||||
1430 | } | ||||||||
1431 | else | ||||||||
1432 | { | ||||||||
1433 | ScTabView::UpdateInputLine(); // InputEnterHandler | ||||||||
1434 | pSh->UpdateInputHandler(); | ||||||||
1435 | } | ||||||||
1436 | } | ||||||||
1437 | if (bDone) // otherwise re-calculate document | ||||||||
1438 | return; | ||||||||
1439 | |||||||||
1440 | weld::WaitObject aWaitObj( GetActiveDialogParent() ); | ||||||||
1441 | if ( pHdl ) | ||||||||
1442 | { | ||||||||
1443 | // tdf97897 set current cell to Dirty to force recalculation of cell | ||||||||
1444 | ScFormulaCell* pFC = m_aDocument.GetFormulaCell( pHdl->GetCursorPos()); | ||||||||
1445 | if (pFC) | ||||||||
1446 | pFC->SetDirty(); | ||||||||
1447 | } | ||||||||
1448 | m_aDocument.CalcFormulaTree(); | ||||||||
1449 | if ( pSh ) | ||||||||
1450 | pSh->UpdateCharts(true); | ||||||||
1451 | |||||||||
1452 | m_aDocument.BroadcastUno( SfxHint( SfxHintId::DataChanged ) ); | ||||||||
1453 | |||||||||
1454 | // If there are charts, then paint everything, so that PostDataChanged | ||||||||
1455 | // and the charts do not come one after the other and parts are painted twice. | ||||||||
1456 | |||||||||
1457 | ScChartListenerCollection* pCharts = m_aDocument.GetChartListenerCollection(); | ||||||||
1458 | if ( pCharts && pCharts->hasListeners() ) | ||||||||
1459 | PostPaintGridAll(); | ||||||||
1460 | else | ||||||||
1461 | PostDataChanged(); | ||||||||
1462 | } | ||||||||
1463 | |||||||||
1464 | void ScDocShell::DoHardRecalc() | ||||||||
1465 | { | ||||||||
1466 | auto start = std::chrono::steady_clock::now(); | ||||||||
1467 | ScDocShellRecalcGuard aGuard(m_aDocument); | ||||||||
1468 | weld::WaitObject aWaitObj( GetActiveDialogParent() ); | ||||||||
1469 | ScTabViewShell* pSh = GetBestViewShell(); | ||||||||
1470 | if ( pSh ) | ||||||||
1471 | { | ||||||||
1472 | ScTabView::UpdateInputLine(); // InputEnterHandler | ||||||||
1473 | pSh->UpdateInputHandler(); | ||||||||
1474 | } | ||||||||
1475 | m_aDocument.CalcAll(); | ||||||||
1476 | GetDocFunc().DetectiveRefresh(); // creates own Undo | ||||||||
1477 | if ( pSh ) | ||||||||
1478 | pSh->UpdateCharts(true); | ||||||||
1479 | |||||||||
1480 | // set notification flags for "calculate" event (used in SfxHintId::DataChanged broadcast) | ||||||||
1481 | // (might check for the presence of any formulas on each sheet) | ||||||||
1482 | SCTAB nTabCount = m_aDocument.GetTableCount(); | ||||||||
1483 | if (m_aDocument.HasAnySheetEventScript( ScSheetEventId::CALCULATE, true )) // search also for VBA handler | ||||||||
1484 | for (SCTAB nTab=0; nTab<nTabCount; nTab++) | ||||||||
1485 | m_aDocument.SetCalcNotification(nTab); | ||||||||
1486 | |||||||||
1487 | // CalcAll doesn't broadcast value changes, so SfxHintId::ScCalcAll is broadcasted globally | ||||||||
1488 | // in addition to SfxHintId::DataChanged. | ||||||||
1489 | m_aDocument.BroadcastUno( SfxHint( SfxHintId::ScCalcAll ) ); | ||||||||
1490 | m_aDocument.BroadcastUno( SfxHint( SfxHintId::DataChanged ) ); | ||||||||
1491 | |||||||||
1492 | // use hard recalc also to disable stream-copying of all sheets | ||||||||
1493 | // (somewhat consistent with charts) | ||||||||
1494 | for (SCTAB nTab=0; nTab<nTabCount; nTab++) | ||||||||
1495 | m_aDocument.SetStreamValid(nTab, false); | ||||||||
1496 | |||||||||
1497 | PostPaintGridAll(); | ||||||||
1498 | auto end = std::chrono::steady_clock::now(); | ||||||||
1499 | SAL_INFO("sc.timing", "ScDocShell::DoHardRecalc(): took " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "sc.timing")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "ScDocShell::DoHardRecalc(): took " << std::chrono::duration_cast<std::chrono::milliseconds >(end - start).count() << "ms") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sc.timing"), ("/home/maarten/src/libreoffice/core/sc/source/ui/docshell/docsh4.cxx" ":" "1499" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "ScDocShell::DoHardRecalc(): took " << std::chrono::duration_cast<std::chrono::milliseconds>( end - start).count() << "ms"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "ScDocShell::DoHardRecalc(): took " << std::chrono::duration_cast<std::chrono::milliseconds >(end - start).count() << "ms"; ::sal::detail::log( ( ::SAL_DETAIL_LOG_LEVEL_INFO), ("sc.timing"), ("/home/maarten/src/libreoffice/core/sc/source/ui/docshell/docsh4.cxx" ":" "1499" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "ScDocShell::DoHardRecalc(): took " << std:: chrono::duration_cast<std::chrono::milliseconds>(end - start ).count() << "ms") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("sc.timing"), ("/home/maarten/src/libreoffice/core/sc/source/ui/docshell/docsh4.cxx" ":" "1499" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "ScDocShell::DoHardRecalc(): took " << std::chrono::duration_cast<std::chrono::milliseconds>( end - start).count() << "ms"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "ScDocShell::DoHardRecalc(): took " << std::chrono::duration_cast<std::chrono::milliseconds >(end - start).count() << "ms"; ::sal::detail::log( ( ::SAL_DETAIL_LOG_LEVEL_INFO), ("sc.timing"), ("/home/maarten/src/libreoffice/core/sc/source/ui/docshell/docsh4.cxx" ":" "1499" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||||
1500 | } | ||||||||
1501 | |||||||||
1502 | void ScDocShell::DoAutoStyle( const ScRange& rRange, const OUString& rStyle ) | ||||||||
1503 | { | ||||||||
1504 | ScStyleSheetPool* pStylePool = m_aDocument.GetStyleSheetPool(); | ||||||||
1505 | ScStyleSheet* pStyleSheet = | ||||||||
1506 | pStylePool->FindCaseIns( rStyle, SfxStyleFamily::Para ); | ||||||||
1507 | if (!pStyleSheet) | ||||||||
1508 | pStyleSheet = static_cast<ScStyleSheet*>( | ||||||||
1509 | pStylePool->Find( ScResId(STR_STYLENAME_STANDARD_CELLreinterpret_cast<char const *>("STR_STYLENAME_STANDARD" "\004" u8"Default Cell Style")), SfxStyleFamily::Para )); | ||||||||
1510 | if (!pStyleSheet) | ||||||||
1511 | return; | ||||||||
1512 | |||||||||
1513 | OSL_ENSURE(rRange.aStart.Tab() == rRange.aEnd.Tab(),do { if (true && (!(rRange.aStart.Tab() == rRange.aEnd .Tab()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/ui/docshell/docsh4.cxx" ":" "1514" ": "), "%s", "DoAutoStyle with several tables"); } } while (false) | ||||||||
1514 | "DoAutoStyle with several tables")do { if (true && (!(rRange.aStart.Tab() == rRange.aEnd .Tab()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/ui/docshell/docsh4.cxx" ":" "1514" ": "), "%s", "DoAutoStyle with several tables"); } } while (false); | ||||||||
1515 | SCTAB nTab = rRange.aStart.Tab(); | ||||||||
1516 | SCCOL nStartCol = rRange.aStart.Col(); | ||||||||
1517 | SCROW nStartRow = rRange.aStart.Row(); | ||||||||
1518 | SCCOL nEndCol = rRange.aEnd.Col(); | ||||||||
1519 | SCROW nEndRow = rRange.aEnd.Row(); | ||||||||
1520 | m_aDocument.ApplyStyleAreaTab( nStartCol, nStartRow, nEndCol, nEndRow, nTab, *pStyleSheet ); | ||||||||
1521 | m_aDocument.ExtendMerge( nStartCol, nStartRow, nEndCol, nEndRow, nTab ); | ||||||||
1522 | PostPaint( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab, PaintPartFlags::Grid ); | ||||||||
1523 | } | ||||||||
1524 | |||||||||
1525 | void ScDocShell::NotifyStyle( const SfxStyleSheetHint& rHint ) | ||||||||
1526 | { | ||||||||
1527 | SfxHintId nId = rHint.GetId(); | ||||||||
1528 | const SfxStyleSheetBase* pStyle = rHint.GetStyleSheet(); | ||||||||
1529 | if (!pStyle) | ||||||||
1530 | return; | ||||||||
1531 | |||||||||
1532 | if ( pStyle->GetFamily() == SfxStyleFamily::Page ) | ||||||||
1533 | { | ||||||||
1534 | if ( nId == SfxHintId::StyleSheetModified ) | ||||||||
1535 | { | ||||||||
1536 | ScDocShellModificator aModificator( *this ); | ||||||||
1537 | |||||||||
1538 | const OUString& aNewName = pStyle->GetName(); | ||||||||
1539 | OUString aOldName = aNewName; | ||||||||
1540 | const SfxStyleSheetModifiedHint* pExtendedHint = dynamic_cast<const SfxStyleSheetModifiedHint*>(&rHint); // name changed? | ||||||||
1541 | if (pExtendedHint) | ||||||||
1542 | aOldName = pExtendedHint->GetOldName(); | ||||||||
1543 | |||||||||
1544 | if ( aNewName != aOldName ) | ||||||||
1545 | m_aDocument.RenamePageStyleInUse( aOldName, aNewName ); | ||||||||
1546 | |||||||||
1547 | SCTAB nTabCount = m_aDocument.GetTableCount(); | ||||||||
1548 | for (SCTAB nTab=0; nTab<nTabCount; nTab++) | ||||||||
1549 | if (m_aDocument.GetPageStyle(nTab) == aNewName) // already adjusted to new | ||||||||
1550 | { | ||||||||
1551 | m_aDocument.PageStyleModified( nTab, aNewName ); | ||||||||
1552 | ScPrintFunc aPrintFunc( this, GetPrinter(), nTab ); | ||||||||
1553 | aPrintFunc.UpdatePages(); | ||||||||
1554 | } | ||||||||
1555 | |||||||||
1556 | aModificator.SetDocumentModified(); | ||||||||
1557 | |||||||||
1558 | if (pExtendedHint) | ||||||||
1559 | { | ||||||||
1560 | SfxBindings* pBindings = GetViewBindings(); | ||||||||
1561 | if (pBindings) | ||||||||
1562 | { | ||||||||
1563 | pBindings->Invalidate( SID_STATUS_PAGESTYLE((26000 + 100) + 15) ); | ||||||||
1564 | pBindings->Invalidate( SID_STYLE_FAMILY4((5000 + 541) + 3) ); | ||||||||
1565 | pBindings->Invalidate( FID_RESET_PRINTZOOM((((26000 + 521) + 50))+82) ); | ||||||||
1566 | pBindings->Invalidate( SID_ATTR_PARA_LEFT_TO_RIGHT( 10000 + 950 ) ); | ||||||||
1567 | pBindings->Invalidate( SID_ATTR_PARA_RIGHT_TO_LEFT( 10000 + 951 ) ); | ||||||||
1568 | } | ||||||||
1569 | } | ||||||||
1570 | } | ||||||||
1571 | } | ||||||||
1572 | else if ( pStyle->GetFamily() == SfxStyleFamily::Para ) | ||||||||
1573 | { | ||||||||
1574 | if ( nId == SfxHintId::StyleSheetModified) | ||||||||
1575 | { | ||||||||
1576 | const OUString& aNewName = pStyle->GetName(); | ||||||||
1577 | OUString aOldName = aNewName; | ||||||||
1578 | const SfxStyleSheetModifiedHint* pExtendedHint = dynamic_cast<const SfxStyleSheetModifiedHint*>(&rHint); | ||||||||
1579 | if (pExtendedHint) | ||||||||
1580 | aOldName = pExtendedHint->GetOldName(); | ||||||||
1581 | if ( aNewName != aOldName ) | ||||||||
1582 | { | ||||||||
1583 | for(SCTAB i = 0; i < m_aDocument.GetTableCount(); ++i) | ||||||||
1584 | { | ||||||||
1585 | ScConditionalFormatList* pList = m_aDocument.GetCondFormList(i); | ||||||||
1586 | if (pList) | ||||||||
1587 | pList->RenameCellStyle( aOldName,aNewName ); | ||||||||
1588 | } | ||||||||
1589 | } | ||||||||
1590 | } | ||||||||
1591 | } | ||||||||
1592 | |||||||||
1593 | // everything else goes via slots... | ||||||||
1594 | } | ||||||||
1595 | |||||||||
1596 | // like in printfun.cxx | ||||||||
1597 | #define ZOOM_MIN10 10 | ||||||||
1598 | |||||||||
1599 | void ScDocShell::SetPrintZoom( SCTAB nTab, sal_uInt16 nScale, sal_uInt16 nPages ) | ||||||||
1600 | { | ||||||||
1601 | OUString aStyleName = m_aDocument.GetPageStyle( nTab ); | ||||||||
1602 | ScStyleSheetPool* pStylePool = m_aDocument.GetStyleSheetPool(); | ||||||||
1603 | SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aStyleName, SfxStyleFamily::Page ); | ||||||||
1604 | OSL_ENSURE( pStyleSheet, "PageStyle not found" )do { if (true && (!(pStyleSheet))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/ui/docshell/docsh4.cxx" ":" "1604" ": "), "%s", "PageStyle not found"); } } while (false ); | ||||||||
1605 | if ( !pStyleSheet ) | ||||||||
1606 | return; | ||||||||
1607 | |||||||||
1608 | ScDocShellModificator aModificator( *this ); | ||||||||
1609 | |||||||||
1610 | SfxItemSet& rSet = pStyleSheet->GetItemSet(); | ||||||||
1611 | const bool bUndo(m_aDocument.IsUndoEnabled()); | ||||||||
1612 | if (bUndo) | ||||||||
1613 | { | ||||||||
1614 | sal_uInt16 nOldScale = rSet.Get(ATTR_PAGE_SCALE).GetValue(); | ||||||||
1615 | sal_uInt16 nOldPages = rSet.Get(ATTR_PAGE_SCALETOPAGES).GetValue(); | ||||||||
1616 | GetUndoManager()->AddUndoAction( std::make_unique<ScUndoPrintZoom>( | ||||||||
1617 | this, nTab, nOldScale, nOldPages, nScale, nPages ) ); | ||||||||
1618 | } | ||||||||
1619 | |||||||||
1620 | rSet.Put( SfxUInt16Item( ATTR_PAGE_SCALE, nScale ) ); | ||||||||
1621 | rSet.Put( SfxUInt16Item( ATTR_PAGE_SCALETOPAGES, nPages ) ); | ||||||||
1622 | |||||||||
1623 | ScPrintFunc aPrintFunc( this, GetPrinter(), nTab ); | ||||||||
1624 | aPrintFunc.UpdatePages(); | ||||||||
1625 | aModificator.SetDocumentModified(); | ||||||||
1626 | |||||||||
1627 | SfxBindings* pBindings = GetViewBindings(); | ||||||||
1628 | if (pBindings) | ||||||||
1629 | pBindings->Invalidate( FID_RESET_PRINTZOOM((((26000 + 521) + 50))+82) ); | ||||||||
1630 | } | ||||||||
1631 | |||||||||
1632 | bool ScDocShell::AdjustPrintZoom( const ScRange& rRange ) | ||||||||
1633 | { | ||||||||
1634 | bool bChange = false; | ||||||||
1635 | SCTAB nTab = rRange.aStart.Tab(); | ||||||||
1636 | |||||||||
1637 | OUString aStyleName = m_aDocument.GetPageStyle( nTab ); | ||||||||
1638 | ScStyleSheetPool* pStylePool = m_aDocument.GetStyleSheetPool(); | ||||||||
1639 | SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aStyleName, SfxStyleFamily::Page ); | ||||||||
1640 | OSL_ENSURE( pStyleSheet, "PageStyle not found" )do { if (true && (!(pStyleSheet))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/ui/docshell/docsh4.cxx" ":" "1640" ": "), "%s", "PageStyle not found"); } } while (false ); | ||||||||
1641 | if ( pStyleSheet ) | ||||||||
1642 | { | ||||||||
1643 | SfxItemSet& rSet = pStyleSheet->GetItemSet(); | ||||||||
1644 | bool bHeaders = rSet.Get(ATTR_PAGE_HEADERS).GetValue(); | ||||||||
1645 | sal_uInt16 nOldScale = rSet.Get(ATTR_PAGE_SCALE).GetValue(); | ||||||||
1646 | sal_uInt16 nOldPages = rSet.Get(ATTR_PAGE_SCALETOPAGES).GetValue(); | ||||||||
1647 | const ScRange* pRepeatCol = m_aDocument.GetRepeatColRange( nTab ); | ||||||||
1648 | const ScRange* pRepeatRow = m_aDocument.GetRepeatRowRange( nTab ); | ||||||||
1649 | |||||||||
1650 | // calculate needed scaling for selection | ||||||||
1651 | |||||||||
1652 | sal_uInt16 nNewScale = nOldScale; | ||||||||
1653 | |||||||||
1654 | long nBlkTwipsX = 0; | ||||||||
1655 | if (bHeaders) | ||||||||
1656 | nBlkTwipsX += long(PRINT_HEADER_WIDTH(1.0 * ((20.0 * 72.0) / 2.54))); | ||||||||
1657 | SCCOL nStartCol = rRange.aStart.Col(); | ||||||||
1658 | SCCOL nEndCol = rRange.aEnd.Col(); | ||||||||
1659 | if ( pRepeatCol && nStartCol >= pRepeatCol->aStart.Col() ) | ||||||||
1660 | { | ||||||||
1661 | for (SCCOL i=pRepeatCol->aStart.Col(); i<=pRepeatCol->aEnd.Col(); i++ ) | ||||||||
1662 | nBlkTwipsX += m_aDocument.GetColWidth( i, nTab ); | ||||||||
1663 | if ( nStartCol <= pRepeatCol->aEnd.Col() ) | ||||||||
1664 | nStartCol = pRepeatCol->aEnd.Col() + 1; | ||||||||
1665 | } | ||||||||
1666 | // legacy compilers' own scope for i | ||||||||
1667 | { | ||||||||
1668 | for ( SCCOL i=nStartCol; i<=nEndCol; i++ ) | ||||||||
1669 | nBlkTwipsX += m_aDocument.GetColWidth( i, nTab ); | ||||||||
1670 | } | ||||||||
1671 | |||||||||
1672 | long nBlkTwipsY = 0; | ||||||||
1673 | if (bHeaders) | ||||||||
1674 | nBlkTwipsY += long(PRINT_HEADER_HEIGHT(12.8 * 20.0)); | ||||||||
1675 | SCROW nStartRow = rRange.aStart.Row(); | ||||||||
1676 | SCROW nEndRow = rRange.aEnd.Row(); | ||||||||
1677 | if ( pRepeatRow && nStartRow >= pRepeatRow->aStart.Row() ) | ||||||||
1678 | { | ||||||||
1679 | nBlkTwipsY += m_aDocument.GetRowHeight( pRepeatRow->aStart.Row(), | ||||||||
1680 | pRepeatRow->aEnd.Row(), nTab ); | ||||||||
1681 | if ( nStartRow <= pRepeatRow->aEnd.Row() ) | ||||||||
1682 | nStartRow = pRepeatRow->aEnd.Row() + 1; | ||||||||
1683 | } | ||||||||
1684 | nBlkTwipsY += m_aDocument.GetRowHeight( nStartRow, nEndRow, nTab ); | ||||||||
1685 | |||||||||
1686 | Size aPhysPage; | ||||||||
1687 | long nHdr, nFtr; | ||||||||
1688 | ScPrintFunc aOldPrFunc( this, GetPrinter(), nTab ); | ||||||||
1689 | aOldPrFunc.GetScaleData( aPhysPage, nHdr, nFtr ); | ||||||||
1690 | nBlkTwipsY += nHdr + nFtr; | ||||||||
1691 | |||||||||
1692 | if ( nBlkTwipsX == 0 ) // hidden columns/rows may lead to 0 | ||||||||
1693 | nBlkTwipsX = 1; | ||||||||
1694 | if ( nBlkTwipsY == 0 ) | ||||||||
1695 | nBlkTwipsY = 1; | ||||||||
1696 | |||||||||
1697 | long nNeeded = std::min( aPhysPage.Width() * 100 / nBlkTwipsX, | ||||||||
1698 | aPhysPage.Height() * 100 / nBlkTwipsY ); | ||||||||
1699 | if ( nNeeded < ZOOM_MIN10 ) | ||||||||
1700 | nNeeded = ZOOM_MIN10; // boundary | ||||||||
1701 | if ( nNeeded < static_cast<long>(nNewScale) ) | ||||||||
1702 | nNewScale = static_cast<sal_uInt16>(nNeeded); | ||||||||
1703 | |||||||||
1704 | bChange = ( nNewScale != nOldScale || nOldPages != 0 ); | ||||||||
1705 | if ( bChange ) | ||||||||
1706 | SetPrintZoom( nTab, nNewScale, 0 ); | ||||||||
1707 | } | ||||||||
1708 | return bChange; | ||||||||
1709 | } | ||||||||
1710 | |||||||||
1711 | void ScDocShell::PageStyleModified( const OUString& rStyleName, bool bApi ) | ||||||||
1712 | { | ||||||||
1713 | ScDocShellModificator aModificator( *this ); | ||||||||
1714 | |||||||||
1715 | SCTAB nTabCount = m_aDocument.GetTableCount(); | ||||||||
1716 | SCTAB nUseTab = MAXTAB+1; | ||||||||
1717 | for (SCTAB nTab=0; nTab<nTabCount && nUseTab>MAXTAB; nTab++) | ||||||||
1718 | if ( m_aDocument.GetPageStyle(nTab) == rStyleName && | ||||||||
1719 | ( !bApi || m_aDocument.GetPageSize(nTab).Width() ) ) | ||||||||
1720 | nUseTab = nTab; | ||||||||
1721 | // at bApi only if breaks already shown | ||||||||
1722 | |||||||||
1723 | if (ValidTab(nUseTab)) // not used -> nothing to do | ||||||||
1724 | { | ||||||||
1725 | bool bWarn = false; | ||||||||
1726 | |||||||||
1727 | ScPrintFunc aPrintFunc( this, GetPrinter(), nUseTab ); //! cope without CountPages | ||||||||
1728 | if (!aPrintFunc.UpdatePages()) // sets breaks on all tabs | ||||||||
1729 | bWarn = true; | ||||||||
1730 | |||||||||
1731 | if (bWarn && !bApi) | ||||||||
1732 | { | ||||||||
1733 | weld::Window* pWin = GetActiveDialogParent(); | ||||||||
1734 | weld::WaitObject aWaitOff(pWin); | ||||||||
1735 | std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(pWin, | ||||||||
1736 | VclMessageType::Info, VclButtonsType::Ok, | ||||||||
1737 | ScResId(STR_PRINT_INVALID_AREAreinterpret_cast<char const *>("STR_PRINT_INVALID_AREA" "\004" u8"Invalid print range")))); | ||||||||
1738 | xInfoBox->run(); | ||||||||
1739 | } | ||||||||
1740 | } | ||||||||
1741 | |||||||||
1742 | aModificator.SetDocumentModified(); | ||||||||
1743 | |||||||||
1744 | SfxBindings* pBindings = GetViewBindings(); | ||||||||
1745 | if (pBindings) | ||||||||
1746 | { | ||||||||
1747 | pBindings->Invalidate( FID_RESET_PRINTZOOM((((26000 + 521) + 50))+82) ); | ||||||||
1748 | pBindings->Invalidate( SID_ATTR_PARA_LEFT_TO_RIGHT( 10000 + 950 ) ); | ||||||||
1749 | pBindings->Invalidate( SID_ATTR_PARA_RIGHT_TO_LEFT( 10000 + 951 ) ); | ||||||||
1750 | } | ||||||||
1751 | } | ||||||||
1752 | |||||||||
1753 | void ScDocShell::ExecutePageStyle( const SfxViewShell& rCaller, | ||||||||
1754 | SfxRequest& rReq, | ||||||||
1755 | SCTAB nCurTab ) | ||||||||
1756 | { | ||||||||
1757 | const SfxItemSet* pReqArgs = rReq.GetArgs(); | ||||||||
1758 | |||||||||
1759 | switch ( rReq.GetSlot() ) | ||||||||
1760 | { | ||||||||
1761 | case SID_STATUS_PAGESTYLE((26000 + 100) + 15): // click on StatusBar control | ||||||||
1762 | case SID_FORMATPAGE((((((((((26000 + 200) + 20)) + 20)) + 20)) + 25)) + 17): | ||||||||
1763 | { | ||||||||
1764 | if ( pReqArgs == nullptr ) | ||||||||
1765 | { | ||||||||
1766 | OUString aOldName = m_aDocument.GetPageStyle( nCurTab ); | ||||||||
1767 | ScStyleSheetPool* pStylePool = m_aDocument.GetStyleSheetPool(); | ||||||||
1768 | SfxStyleSheetBase* pStyleSheet | ||||||||
1769 | = pStylePool->Find( aOldName, SfxStyleFamily::Page ); | ||||||||
1770 | |||||||||
1771 | OSL_ENSURE( pStyleSheet, "PageStyle not found! :-/" )do { if (true && (!(pStyleSheet))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/ui/docshell/docsh4.cxx" ":" "1771" ": "), "%s", "PageStyle not found! :-/"); } } while (false); | ||||||||
1772 | |||||||||
1773 | if ( pStyleSheet ) | ||||||||
1774 | { | ||||||||
1775 | ScStyleSaveData aOldData; | ||||||||
1776 | const bool bUndo(m_aDocument.IsUndoEnabled()); | ||||||||
1777 | if (bUndo) | ||||||||
1778 | aOldData.InitFromStyle( pStyleSheet ); | ||||||||
1779 | |||||||||
1780 | SfxItemSet& rStyleSet = pStyleSheet->GetItemSet(); | ||||||||
1781 | rStyleSet.MergeRange( XATTR_FILL_FIRST, XATTR_FILL_LAST ); | ||||||||
1782 | |||||||||
1783 | ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create(); | ||||||||
1784 | |||||||||
1785 | VclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateScStyleDlg(GetActiveDialogParent(), *pStyleSheet, true)); | ||||||||
1786 | |||||||||
1787 | auto pRequest = std::make_shared<SfxRequest>(rReq); | ||||||||
1788 | rReq.Ignore(); // the 'old' request is not relevant any more | ||||||||
1789 | pDlg->StartExecuteAsync([this, pDlg, pRequest, pStyleSheet, aOldData, aOldName, &rStyleSet, nCurTab, &rCaller, bUndo](sal_Int32 nResult){ | ||||||||
1790 | if ( nResult == RET_OK ) | ||||||||
1791 | { | ||||||||
1792 | const SfxItemSet* pOutSet = pDlg->GetOutputItemSet(); | ||||||||
1793 | |||||||||
1794 | weld::WaitObject aWait( GetActiveDialogParent() ); | ||||||||
1795 | |||||||||
1796 | OUString aNewName = pStyleSheet->GetName(); | ||||||||
1797 | if ( aNewName != aOldName && | ||||||||
1798 | m_aDocument.RenamePageStyleInUse( aOldName, aNewName ) ) | ||||||||
1799 | { | ||||||||
1800 | SfxBindings* pBindings = GetViewBindings(); | ||||||||
1801 | if (pBindings) | ||||||||
1802 | { | ||||||||
1803 | pBindings->Invalidate( SID_STATUS_PAGESTYLE((26000 + 100) + 15) ); | ||||||||
1804 | pBindings->Invalidate( FID_RESET_PRINTZOOM((((26000 + 521) + 50))+82) ); | ||||||||
1805 | } | ||||||||
1806 | } | ||||||||
1807 | |||||||||
1808 | if ( pOutSet ) | ||||||||
1809 | m_aDocument.ModifyStyleSheet( *pStyleSheet, *pOutSet ); | ||||||||
1810 | |||||||||
1811 | // memorizing for GetState(): | ||||||||
1812 | GetPageOnFromPageStyleSet( &rStyleSet, nCurTab, m_bHeaderOn, m_bFooterOn ); | ||||||||
1813 | rCaller.GetViewFrame()->GetBindings().Invalidate( SID_HFEDIT((((26000 + 200) + 20)) + 15) ); | ||||||||
1814 | |||||||||
1815 | ScStyleSaveData aNewData; | ||||||||
1816 | aNewData.InitFromStyle( pStyleSheet ); | ||||||||
1817 | if (bUndo) | ||||||||
1818 | { | ||||||||
1819 | GetUndoManager()->AddUndoAction( | ||||||||
1820 | std::make_unique<ScUndoModifyStyle>( this, SfxStyleFamily::Page, | ||||||||
1821 | aOldData, aNewData ) ); | ||||||||
1822 | } | ||||||||
1823 | |||||||||
1824 | PageStyleModified( aNewName, false ); | ||||||||
1825 | pRequest->Done(); | ||||||||
1826 | } | ||||||||
1827 | pDlg->disposeOnce(); | ||||||||
1828 | }); | ||||||||
1829 | } | ||||||||
1830 | } | ||||||||
1831 | } | ||||||||
1832 | break; | ||||||||
1833 | |||||||||
1834 | case SID_HFEDIT((((26000 + 200) + 20)) + 15): | ||||||||
1835 | { | ||||||||
1836 | if ( pReqArgs == nullptr ) | ||||||||
1837 | { | ||||||||
1838 | OUString aStr( m_aDocument.GetPageStyle( nCurTab ) ); | ||||||||
1839 | |||||||||
1840 | ScStyleSheetPool* pStylePool | ||||||||
1841 | = m_aDocument.GetStyleSheetPool(); | ||||||||
1842 | |||||||||
1843 | SfxStyleSheetBase* pStyleSheet | ||||||||
1844 | = pStylePool->Find( aStr, SfxStyleFamily::Page ); | ||||||||
1845 | |||||||||
1846 | OSL_ENSURE( pStyleSheet, "PageStyle not found! :-/" )do { if (true && (!(pStyleSheet))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/ui/docshell/docsh4.cxx" ":" "1846" ": "), "%s", "PageStyle not found! :-/"); } } while (false); | ||||||||
1847 | |||||||||
1848 | if ( pStyleSheet ) | ||||||||
1849 | { | ||||||||
1850 | SfxItemSet& rStyleSet = pStyleSheet->GetItemSet(); | ||||||||
1851 | |||||||||
1852 | SvxPageUsage eUsage = rStyleSet.Get( ATTR_PAGE ).GetPageUsage(); | ||||||||
1853 | bool bShareHeader = rStyleSet | ||||||||
1854 | .Get(ATTR_PAGE_HEADERSET) | ||||||||
1855 | .GetItemSet() | ||||||||
1856 | .Get(ATTR_PAGE_SHARED) | ||||||||
1857 | .GetValue(); | ||||||||
1858 | bool bShareFooter = rStyleSet | ||||||||
1859 | .Get(ATTR_PAGE_FOOTERSET) | ||||||||
1860 | .GetItemSet() | ||||||||
1861 | .Get(ATTR_PAGE_SHARED) | ||||||||
1862 | .GetValue(); | ||||||||
1863 | sal_uInt16 nResId = 0; | ||||||||
1864 | |||||||||
1865 | switch ( eUsage ) | ||||||||
1866 | { | ||||||||
1867 | case SvxPageUsage::Left: | ||||||||
1868 | case SvxPageUsage::Right: | ||||||||
1869 | { | ||||||||
1870 | if ( m_bHeaderOn && m_bFooterOn ) | ||||||||
1871 | nResId = RID_SCDLG_HFEDIT(((((20000 +5000)+100) + 554) + 100) + 50); | ||||||||
1872 | else if ( SvxPageUsage::Right == eUsage ) | ||||||||
1873 | { | ||||||||
1874 | if ( !m_bHeaderOn && m_bFooterOn ) | ||||||||
1875 | nResId = RID_SCDLG_HFEDIT_RIGHTFOOTER(((((20000 +5000)+100) + 554) + 100) + 67); | ||||||||
1876 | else if ( m_bHeaderOn && !m_bFooterOn ) | ||||||||
1877 | nResId = RID_SCDLG_HFEDIT_RIGHTHEADER(((((20000 +5000)+100) + 554) + 100) + 65); | ||||||||
1878 | } | ||||||||
1879 | else | ||||||||
1880 | { | ||||||||
1881 | // #69193a# respect "shared" setting | ||||||||
1882 | if ( !m_bHeaderOn && m_bFooterOn ) | ||||||||
1883 | nResId = bShareFooter ? | ||||||||
1884 | RID_SCDLG_HFEDIT_RIGHTFOOTER(((((20000 +5000)+100) + 554) + 100) + 67) : | ||||||||
1885 | RID_SCDLG_HFEDIT_LEFTFOOTER(((((20000 +5000)+100) + 554) + 100) + 66); | ||||||||
1886 | else if ( m_bHeaderOn && !m_bFooterOn ) | ||||||||
1887 | nResId = bShareHeader ? | ||||||||
1888 | RID_SCDLG_HFEDIT_RIGHTHEADER(((((20000 +5000)+100) + 554) + 100) + 65) : | ||||||||
1889 | RID_SCDLG_HFEDIT_LEFTHEADER(((((20000 +5000)+100) + 554) + 100) + 64); | ||||||||
1890 | } | ||||||||
1891 | } | ||||||||
1892 | break; | ||||||||
1893 | |||||||||
1894 | case SvxPageUsage::Mirror: | ||||||||
1895 | case SvxPageUsage::All: | ||||||||
1896 | default: | ||||||||
1897 | { | ||||||||
1898 | if ( !bShareHeader && !bShareFooter ) | ||||||||
1899 | { | ||||||||
1900 | if ( m_bHeaderOn && m_bFooterOn ) | ||||||||
1901 | nResId = RID_SCDLG_HFEDIT_ALL(((((20000 +5000)+100) + 554) + 100) + 51); | ||||||||
1902 | else if ( !m_bHeaderOn && m_bFooterOn ) | ||||||||
1903 | nResId = RID_SCDLG_HFEDIT_FOOTER(((((20000 +5000)+100) + 554) + 100) + 69); | ||||||||
1904 | else if ( m_bHeaderOn && !m_bFooterOn ) | ||||||||
1905 | nResId = RID_SCDLG_HFEDIT_HEADER(((((20000 +5000)+100) + 554) + 100) + 68); | ||||||||
1906 | } | ||||||||
1907 | else if ( bShareHeader && bShareFooter ) | ||||||||
1908 | { | ||||||||
1909 | if ( m_bHeaderOn && m_bFooterOn ) | ||||||||
1910 | nResId = RID_SCDLG_HFEDIT(((((20000 +5000)+100) + 554) + 100) + 50); | ||||||||
1911 | else | ||||||||
1912 | { | ||||||||
1913 | if ( !m_bHeaderOn && m_bFooterOn ) | ||||||||
1914 | nResId = RID_SCDLG_HFEDIT_RIGHTFOOTER(((((20000 +5000)+100) + 554) + 100) + 67); | ||||||||
1915 | else if ( m_bHeaderOn && !m_bFooterOn ) | ||||||||
1916 | nResId = RID_SCDLG_HFEDIT_RIGHTHEADER(((((20000 +5000)+100) + 554) + 100) + 65); | ||||||||
1917 | } | ||||||||
1918 | } | ||||||||
1919 | else if ( !bShareHeader && bShareFooter ) | ||||||||
1920 | { | ||||||||
1921 | if ( m_bHeaderOn && m_bFooterOn ) | ||||||||
1922 | nResId = RID_SCDLG_HFEDIT_SFTR(((((20000 +5000)+100) + 554) + 100) + 63); | ||||||||
1923 | else if ( !m_bHeaderOn && m_bFooterOn ) | ||||||||
1924 | nResId = RID_SCDLG_HFEDIT_RIGHTFOOTER(((((20000 +5000)+100) + 554) + 100) + 67); | ||||||||
1925 | else if ( m_bHeaderOn && !m_bFooterOn ) | ||||||||
1926 | nResId = RID_SCDLG_HFEDIT_HEADER(((((20000 +5000)+100) + 554) + 100) + 68); | ||||||||
1927 | } | ||||||||
1928 | else if ( bShareHeader && !bShareFooter ) | ||||||||
1929 | { | ||||||||
1930 | if ( m_bHeaderOn && m_bFooterOn ) | ||||||||
1931 | nResId = RID_SCDLG_HFEDIT_SHDR(((((20000 +5000)+100) + 554) + 100) + 62); | ||||||||
1932 | else if ( !m_bHeaderOn && m_bFooterOn ) | ||||||||
1933 | nResId = RID_SCDLG_HFEDIT_FOOTER(((((20000 +5000)+100) + 554) + 100) + 69); | ||||||||
1934 | else if ( m_bHeaderOn && !m_bFooterOn ) | ||||||||
1935 | nResId = RID_SCDLG_HFEDIT_RIGHTHEADER(((((20000 +5000)+100) + 554) + 100) + 65); | ||||||||
1936 | } | ||||||||
1937 | } | ||||||||
1938 | } | ||||||||
1939 | |||||||||
1940 | ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create(); | ||||||||
1941 | |||||||||
1942 | VclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateScHFEditDlg( | ||||||||
1943 | GetActiveDialogParent(), | ||||||||
1944 | rStyleSet, | ||||||||
1945 | aStr, | ||||||||
1946 | nResId)); | ||||||||
1947 | auto xRequest = std::make_shared<SfxRequest>(rReq); | ||||||||
1948 | rReq.Ignore(); // the 'old' request is not relevant any more | ||||||||
1949 | pDlg->StartExecuteAsync([this, pDlg, pStyleSheet, xRequest](sal_Int32 nResult){ | ||||||||
1950 | if ( nResult == RET_OK ) | ||||||||
1951 | { | ||||||||
1952 | const SfxItemSet* pOutSet = pDlg->GetOutputItemSet(); | ||||||||
1953 | |||||||||
1954 | if ( pOutSet ) | ||||||||
1955 | m_aDocument.ModifyStyleSheet( *pStyleSheet, *pOutSet ); | ||||||||
1956 | |||||||||
1957 | SetDocumentModified(); | ||||||||
1958 | xRequest->Done(); | ||||||||
1959 | } | ||||||||
1960 | pDlg->disposeOnce(); | ||||||||
1961 | }); | ||||||||
1962 | } | ||||||||
1963 | } | ||||||||
1964 | } | ||||||||
1965 | break; | ||||||||
1966 | |||||||||
1967 | default: | ||||||||
1968 | break; | ||||||||
1969 | } | ||||||||
1970 | } | ||||||||
1971 | |||||||||
1972 | void ScDocShell::GetStatePageStyle( SfxItemSet& rSet, | ||||||||
1973 | SCTAB nCurTab ) | ||||||||
1974 | { | ||||||||
1975 | SfxWhichIter aIter(rSet); | ||||||||
1976 | sal_uInt16 nWhich = aIter.FirstWhich(); | ||||||||
1977 | while ( nWhich ) | ||||||||
1978 | { | ||||||||
1979 | switch (nWhich) | ||||||||
1980 | { | ||||||||
1981 | case SID_STATUS_PAGESTYLE((26000 + 100) + 15): | ||||||||
1982 | rSet.Put( SfxStringItem( nWhich, m_aDocument.GetPageStyle( nCurTab ) ) ); | ||||||||
1983 | break; | ||||||||
1984 | |||||||||
1985 | case SID_HFEDIT((((26000 + 200) + 20)) + 15): | ||||||||
1986 | { | ||||||||
1987 | OUString aStr = m_aDocument.GetPageStyle( nCurTab ); | ||||||||
1988 | ScStyleSheetPool* pStylePool = m_aDocument.GetStyleSheetPool(); | ||||||||
1989 | SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aStr, SfxStyleFamily::Page ); | ||||||||
1990 | |||||||||
1991 | OSL_ENSURE( pStyleSheet, "PageStyle not found! :-/" )do { if (true && (!(pStyleSheet))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/ui/docshell/docsh4.cxx" ":" "1991" ": "), "%s", "PageStyle not found! :-/"); } } while (false); | ||||||||
1992 | |||||||||
1993 | if ( pStyleSheet ) | ||||||||
1994 | { | ||||||||
1995 | SfxItemSet& rStyleSet = pStyleSheet->GetItemSet(); | ||||||||
1996 | GetPageOnFromPageStyleSet( &rStyleSet, nCurTab, m_bHeaderOn, m_bFooterOn ); | ||||||||
1997 | |||||||||
1998 | if ( !m_bHeaderOn && !m_bFooterOn ) | ||||||||
1999 | rSet.DisableItem( nWhich ); | ||||||||
2000 | } | ||||||||
2001 | } | ||||||||
2002 | break; | ||||||||
2003 | } | ||||||||
2004 | |||||||||
2005 | nWhich = aIter.NextWhich(); | ||||||||
2006 | } | ||||||||
2007 | } | ||||||||
2008 | |||||||||
2009 | void ScDocShell::GetState( SfxItemSet &rSet ) | ||||||||
2010 | { | ||||||||
2011 | bool bTabView = GetBestViewShell() != nullptr; | ||||||||
2012 | |||||||||
2013 | SfxWhichIter aIter(rSet); | ||||||||
2014 | for (sal_uInt16 nWhich = aIter.FirstWhich(); nWhich; nWhich = aIter.NextWhich()) | ||||||||
2015 | { | ||||||||
2016 | if (!bTabView) | ||||||||
2017 | { | ||||||||
2018 | rSet.DisableItem(nWhich); | ||||||||
2019 | continue; | ||||||||
2020 | } | ||||||||
2021 | |||||||||
2022 | switch (nWhich) | ||||||||
2023 | { | ||||||||
2024 | case FID_AUTO_CALC((((((((((((26000 + 200) + 20)) + 20)) + 20)) + 25)) + 22)) + 3): | ||||||||
2025 | if ( m_aDocument.GetHardRecalcState() != ScDocument::HardRecalcState::OFF ) | ||||||||
2026 | rSet.DisableItem( nWhich ); | ||||||||
2027 | else | ||||||||
2028 | rSet.Put( SfxBoolItem( nWhich, m_aDocument.GetAutoCalc() ) ); | ||||||||
2029 | break; | ||||||||
2030 | |||||||||
2031 | case FID_CHG_RECORD((((26000 + 200) + 20)) + 18): | ||||||||
2032 | if ( IsDocShared() ) | ||||||||
2033 | rSet.DisableItem( nWhich ); | ||||||||
2034 | else | ||||||||
2035 | rSet.Put( SfxBoolItem( nWhich, | ||||||||
2036 | m_aDocument.GetChangeTrack() != nullptr ) ); | ||||||||
2037 | break; | ||||||||
2038 | |||||||||
2039 | case SID_CHG_PROTECT((26000) + 84): | ||||||||
2040 | { | ||||||||
2041 | ScChangeTrack* pChangeTrack = m_aDocument.GetChangeTrack(); | ||||||||
2042 | if ( pChangeTrack && !IsDocShared() ) | ||||||||
2043 | rSet.Put( SfxBoolItem( nWhich, | ||||||||
2044 | pChangeTrack->IsProtected() ) ); | ||||||||
2045 | else | ||||||||
2046 | rSet.DisableItem( nWhich ); | ||||||||
2047 | } | ||||||||
2048 | break; | ||||||||
2049 | |||||||||
2050 | case SID_DOCUMENT_COMPARE(5000 + 1586): | ||||||||
2051 | { | ||||||||
2052 | if ( IsDocShared() ) | ||||||||
2053 | { | ||||||||
2054 | rSet.DisableItem( nWhich ); | ||||||||
2055 | } | ||||||||
2056 | } | ||||||||
2057 | break; | ||||||||
2058 | |||||||||
2059 | // When a formula is edited, FID_RECALC must be enabled in any case. Recalc for | ||||||||
2060 | // the doc was disabled once because of a bug if AutoCalc was on, but is now | ||||||||
2061 | // always enabled because of another bug. | ||||||||
2062 | |||||||||
2063 | case SID_TABLES_COUNT((((26000 + 521) + 50))+83): | ||||||||
2064 | rSet.Put( SfxInt16Item( nWhich, m_aDocument.GetTableCount() ) ); | ||||||||
2065 | break; | ||||||||
2066 | |||||||||
2067 | case SID_ATTR_YEAR2000(((((10000 + 1499) + 1) + 499) + 1) + 87) : | ||||||||
2068 | rSet.Put( SfxUInt16Item( nWhich, | ||||||||
2069 | m_aDocument.GetDocOptions().GetYear2000() ) ); | ||||||||
2070 | break; | ||||||||
2071 | |||||||||
2072 | case SID_SHARE_DOC((((((((((((26000 + 200) + 20)) + 20)) + 20)) + 25)) + 22)) + 11): | ||||||||
2073 | { | ||||||||
2074 | if ( IsReadOnly() || GetObjectShell()->isExportLocked() ) | ||||||||
2075 | { | ||||||||
2076 | rSet.DisableItem( nWhich ); | ||||||||
2077 | } | ||||||||
2078 | } | ||||||||
2079 | break; | ||||||||
2080 | |||||||||
2081 | case SID_ATTR_CHAR_FONTLIST( 10000 + 22 ): | ||||||||
2082 | rSet.Put( SvxFontListItem( m_pImpl->pFontList.get(), nWhich ) ); | ||||||||
2083 | break; | ||||||||
2084 | |||||||||
2085 | case SID_NOTEBOOKBAR(10000 + 338): | ||||||||
2086 | { | ||||||||
2087 | if (GetViewBindings()) | ||||||||
2088 | { | ||||||||
2089 | bool bVisible = sfx2::SfxNotebookBar::StateMethod(*GetViewBindings(), | ||||||||
2090 | "modules/scalc/ui/"); | ||||||||
2091 | rSet.Put( SfxBoolItem( SID_NOTEBOOKBAR(10000 + 338), bVisible ) ); | ||||||||
2092 | } | ||||||||
2093 | } | ||||||||
2094 | break; | ||||||||
2095 | |||||||||
2096 | case SID_LANGUAGE_STATUS( 10000 + 1067 ): | ||||||||
2097 | { | ||||||||
2098 | LanguageType eLatin, eCjk, eCtl; | ||||||||
2099 | |||||||||
2100 | GetDocument().GetLanguage( eLatin, eCjk, eCtl ); | ||||||||
2101 | OUString sLanguage = SvtLanguageTable::GetLanguageString(eLatin); | ||||||||
2102 | if (comphelper::LibreOfficeKit::isActive()) { | ||||||||
2103 | if (eLatin == LANGUAGE_NONELanguageType(0x00FF)) | ||||||||
2104 | sLanguage += ";-"; | ||||||||
2105 | else | ||||||||
2106 | sLanguage += ";" + LanguageTag(eLatin).getBcp47(false); | ||||||||
2107 | } | ||||||||
2108 | rSet.Put(SfxStringItem(nWhich, sLanguage)); | ||||||||
2109 | } | ||||||||
2110 | break; | ||||||||
2111 | |||||||||
2112 | default: | ||||||||
2113 | { | ||||||||
2114 | } | ||||||||
2115 | break; | ||||||||
2116 | } | ||||||||
2117 | } | ||||||||
2118 | } | ||||||||
2119 | |||||||||
2120 | void ScDocShell::Draw( OutputDevice* pDev, const JobSetup & /* rSetup */, sal_uInt16 nAspect ) | ||||||||
2121 | { | ||||||||
2122 | |||||||||
2123 | SCTAB nVisTab = m_aDocument.GetVisibleTab(); | ||||||||
2124 | if (!m_aDocument.HasTable(nVisTab)) | ||||||||
2125 | return; | ||||||||
2126 | |||||||||
2127 | ComplexTextLayoutFlags nOldLayoutMode = pDev->GetLayoutMode(); | ||||||||
2128 | pDev->SetLayoutMode( ComplexTextLayoutFlags::Default ); // even if it's the same, to get the metafile action | ||||||||
2129 | |||||||||
2130 | if ( nAspect == ASPECT_THUMBNAIL2 ) | ||||||||
2131 | { | ||||||||
2132 | tools::Rectangle aBoundRect = GetVisArea( ASPECT_THUMBNAIL2 ); | ||||||||
2133 | ScViewData aTmpData( *this, nullptr ); | ||||||||
2134 | aTmpData.SetTabNo(nVisTab); | ||||||||
2135 | SnapVisArea( aBoundRect ); | ||||||||
2136 | aTmpData.SetScreen( aBoundRect ); | ||||||||
2137 | ScPrintFunc::DrawToDev( m_aDocument, pDev, 1.0, aBoundRect, &aTmpData, true ); | ||||||||
2138 | } | ||||||||
2139 | else | ||||||||
2140 | { | ||||||||
2141 | tools::Rectangle aOldArea = SfxObjectShell::GetVisArea(); | ||||||||
2142 | tools::Rectangle aNewArea = aOldArea; | ||||||||
2143 | ScViewData aTmpData( *this, nullptr ); | ||||||||
2144 | aTmpData.SetTabNo(nVisTab); | ||||||||
2145 | SnapVisArea( aNewArea ); | ||||||||
2146 | if ( aNewArea != aOldArea && (m_aDocument.GetPosLeft() > 0 || m_aDocument.GetPosTop() > 0) ) | ||||||||
2147 | SfxObjectShell::SetVisArea( aNewArea ); | ||||||||
2148 | aTmpData.SetScreen( aNewArea ); | ||||||||
2149 | ScPrintFunc::DrawToDev( m_aDocument, pDev, 1.0, aNewArea, &aTmpData, true ); | ||||||||
2150 | } | ||||||||
2151 | |||||||||
2152 | pDev->SetLayoutMode( nOldLayoutMode ); | ||||||||
2153 | } | ||||||||
2154 | |||||||||
2155 | tools::Rectangle ScDocShell::GetVisArea( sal_uInt16 nAspect ) const | ||||||||
2156 | { | ||||||||
2157 | SfxObjectCreateMode eShellMode = GetCreateMode(); | ||||||||
2158 | if ( eShellMode == SfxObjectCreateMode::ORGANIZER ) | ||||||||
2159 | { | ||||||||
2160 | // without contents we also don't know how large are the contents; | ||||||||
2161 | // return empty rectangle, it will then be calculated after the loading | ||||||||
2162 | return tools::Rectangle(); | ||||||||
2163 | } | ||||||||
2164 | |||||||||
2165 | if( nAspect == ASPECT_THUMBNAIL2 ) | ||||||||
2166 | { | ||||||||
2167 | SCTAB nVisTab = m_aDocument.GetVisibleTab(); | ||||||||
2168 | if (!m_aDocument.HasTable(nVisTab)) | ||||||||
2169 | { | ||||||||
2170 | nVisTab = 0; | ||||||||
2171 | const_cast<ScDocShell*>(this)->m_aDocument.SetVisibleTab(nVisTab); | ||||||||
2172 | } | ||||||||
2173 | Size aSize = m_aDocument.GetPageSize(nVisTab); | ||||||||
2174 | const long SC_PREVIEW_SIZE_X = 10000; | ||||||||
2175 | const long SC_PREVIEW_SIZE_Y = 12400; | ||||||||
2176 | tools::Rectangle aArea( 0,0, SC_PREVIEW_SIZE_X, SC_PREVIEW_SIZE_Y); | ||||||||
2177 | if (aSize.Width() > aSize.Height()) | ||||||||
2178 | { | ||||||||
2179 | aArea.SetRight( SC_PREVIEW_SIZE_Y ); | ||||||||
2180 | aArea.SetBottom( SC_PREVIEW_SIZE_X ); | ||||||||
2181 | } | ||||||||
2182 | |||||||||
2183 | bool bNegativePage = m_aDocument.IsNegativePage( m_aDocument.GetVisibleTab() ); | ||||||||
2184 | if ( bNegativePage ) | ||||||||
2185 | ScDrawLayer::MirrorRectRTL( aArea ); | ||||||||
2186 | SnapVisArea( aArea ); | ||||||||
2187 | return aArea; | ||||||||
2188 | } | ||||||||
2189 | else if( nAspect == ASPECT_CONTENT1 && eShellMode != SfxObjectCreateMode::EMBEDDED ) | ||||||||
2190 | { | ||||||||
2191 | // fetch visarea like after loading | ||||||||
2192 | |||||||||
2193 | SCTAB nVisTab = m_aDocument.GetVisibleTab(); | ||||||||
2194 | if (!m_aDocument.HasTable(nVisTab)) | ||||||||
2195 | { | ||||||||
2196 | nVisTab = 0; | ||||||||
2197 | const_cast<ScDocShell*>(this)->m_aDocument.SetVisibleTab(nVisTab); | ||||||||
2198 | } | ||||||||
2199 | SCCOL nStartCol; | ||||||||
2200 | SCROW nStartRow; | ||||||||
2201 | m_aDocument.GetDataStart( nVisTab, nStartCol, nStartRow ); | ||||||||
2202 | SCCOL nEndCol; | ||||||||
2203 | SCROW nEndRow; | ||||||||
2204 | m_aDocument.GetPrintArea( nVisTab, nEndCol, nEndRow ); | ||||||||
2205 | if (nStartCol>nEndCol) | ||||||||
2206 | nStartCol = nEndCol; | ||||||||
2207 | if (nStartRow>nEndRow) | ||||||||
2208 | nStartRow = nEndRow; | ||||||||
2209 | tools::Rectangle aNewArea = m_aDocument | ||||||||
2210 | .GetMMRect( nStartCol,nStartRow, nEndCol,nEndRow, nVisTab ); | ||||||||
2211 | return aNewArea; | ||||||||
2212 | } | ||||||||
2213 | else | ||||||||
2214 | return SfxObjectShell::GetVisArea( nAspect ); | ||||||||
2215 | } | ||||||||
2216 | |||||||||
2217 | namespace { | ||||||||
2218 | |||||||||
2219 | [[nodiscard]] | ||||||||
2220 | long SnapHorizontal( const ScDocument& rDoc, SCTAB nTab, long nVal, SCCOL& rStartCol ) | ||||||||
2221 | { | ||||||||
2222 | SCCOL nCol = 0; | ||||||||
2223 | long nTwips = static_cast<long>(nVal / HMM_PER_TWIPS((2.54 / (20.0 * 72.0)) * 1000.0)); | ||||||||
2224 | long nSnap = 0; | ||||||||
2225 | while ( nCol<rDoc.MaxCol() ) | ||||||||
2226 | { | ||||||||
2227 | long nAdd = rDoc.GetColWidth(nCol, nTab); | ||||||||
2228 | if ( nSnap + nAdd/2 < nTwips || nCol < rStartCol ) | ||||||||
2229 | { | ||||||||
2230 | nSnap += nAdd; | ||||||||
2231 | ++nCol; | ||||||||
2232 | } | ||||||||
2233 | else | ||||||||
2234 | break; | ||||||||
2235 | } | ||||||||
2236 | nVal = static_cast<long>( nSnap * HMM_PER_TWIPS((2.54 / (20.0 * 72.0)) * 1000.0) ); | ||||||||
2237 | rStartCol = nCol; | ||||||||
2238 | return nVal; | ||||||||
2239 | } | ||||||||
2240 | |||||||||
2241 | [[nodiscard]] | ||||||||
2242 | long SnapVertical( const ScDocument& rDoc, SCTAB nTab, long nVal, SCROW& rStartRow ) | ||||||||
2243 | { | ||||||||
2244 | SCROW nRow = 0; | ||||||||
2245 | long nTwips = static_cast<long>(nVal / HMM_PER_TWIPS((2.54 / (20.0 * 72.0)) * 1000.0)); | ||||||||
2246 | long nSnap = 0; | ||||||||
2247 | |||||||||
2248 | bool bFound = false; | ||||||||
2249 | for (SCROW i = nRow; i <= rDoc.MaxRow(); ++i) | ||||||||
2250 | { | ||||||||
2251 | SCROW nLastRow; | ||||||||
2252 | if (rDoc.RowHidden(i, nTab, nullptr, &nLastRow)) | ||||||||
2253 | { | ||||||||
2254 | i = nLastRow; | ||||||||
2255 | continue; | ||||||||
2256 | } | ||||||||
2257 | |||||||||
2258 | nRow = i; | ||||||||
2259 | long nAdd = rDoc.GetRowHeight(i, nTab); | ||||||||
2260 | if ( nSnap + nAdd/2 < nTwips || nRow < rStartRow ) | ||||||||
2261 | { | ||||||||
2262 | nSnap += nAdd; | ||||||||
2263 | ++nRow; | ||||||||
2264 | } | ||||||||
2265 | else | ||||||||
2266 | { | ||||||||
2267 | bFound = true; | ||||||||
2268 | break; | ||||||||
2269 | } | ||||||||
2270 | } | ||||||||
2271 | if (!bFound) | ||||||||
2272 | nRow = rDoc.MaxRow(); // all hidden down to the bottom | ||||||||
2273 | |||||||||
2274 | nVal = static_cast<long>( nSnap * HMM_PER_TWIPS((2.54 / (20.0 * 72.0)) * 1000.0) ); | ||||||||
2275 | rStartRow = nRow; | ||||||||
2276 | return nVal; | ||||||||
2277 | } | ||||||||
2278 | |||||||||
2279 | } | ||||||||
2280 | |||||||||
2281 | void ScDocShell::SnapVisArea( tools::Rectangle& rRect ) const | ||||||||
2282 | { | ||||||||
2283 | SCTAB nTab = m_aDocument.GetVisibleTab(); | ||||||||
2284 | long nOrigTop = rRect.Top(); | ||||||||
2285 | long nOrigLeft = rRect.Left(); | ||||||||
2286 | bool bNegativePage = m_aDocument.IsNegativePage( nTab ); | ||||||||
2287 | if ( bNegativePage ) | ||||||||
2288 | ScDrawLayer::MirrorRectRTL( rRect ); // calculate with positive (LTR) values | ||||||||
2289 | |||||||||
2290 | SCCOL nCol = m_aDocument.GetPosLeft(); | ||||||||
2291 | long nSetLeft = SnapHorizontal( m_aDocument, nTab, rRect.Left(), nCol ); | ||||||||
2292 | rRect.SetLeft( nSetLeft ); | ||||||||
2293 | ++nCol; // at least one column | ||||||||
2294 | long nCorrectionLeft = (nOrigLeft == 0 && nCol > 0) ? nSetLeft : 0; // initial correction | ||||||||
2295 | rRect.SetRight( SnapHorizontal( m_aDocument, nTab, rRect.Right() + nCorrectionLeft, nCol )); | ||||||||
2296 | |||||||||
2297 | SCROW nRow = m_aDocument.GetPosTop(); | ||||||||
2298 | long nSetTop = SnapVertical( m_aDocument, nTab, rRect.Top(), nRow ); | ||||||||
2299 | rRect.SetTop( nSetTop ); | ||||||||
2300 | ++nRow; // at least one row | ||||||||
2301 | long nCorrectionTop = (nOrigTop == 0 && nRow > 0) ? nSetTop : 0; // initial correction | ||||||||
2302 | rRect.SetBottom( SnapVertical( m_aDocument, nTab, rRect.Bottom() + nCorrectionTop, nRow )); | ||||||||
2303 | |||||||||
2304 | if ( bNegativePage ) | ||||||||
2305 | ScDrawLayer::MirrorRectRTL( rRect ); // back to real rectangle | ||||||||
2306 | } | ||||||||
2307 | |||||||||
2308 | void ScDocShell::GetPageOnFromPageStyleSet( const SfxItemSet* pStyleSet, | ||||||||
2309 | SCTAB nCurTab, | ||||||||
2310 | bool& rbHeader, | ||||||||
2311 | bool& rbFooter ) | ||||||||
2312 | { | ||||||||
2313 | if ( !pStyleSet ) | ||||||||
2314 | { | ||||||||
2315 | ScStyleSheetPool* pStylePool = m_aDocument.GetStyleSheetPool(); | ||||||||
2316 | SfxStyleSheetBase* pStyleSheet = pStylePool-> | ||||||||
2317 | Find( m_aDocument.GetPageStyle( nCurTab ), | ||||||||
2318 | SfxStyleFamily::Page ); | ||||||||
2319 | |||||||||
2320 | OSL_ENSURE( pStyleSheet, "PageStyle not found! :-/" )do { if (true && (!(pStyleSheet))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/ui/docshell/docsh4.cxx" ":" "2320" ": "), "%s", "PageStyle not found! :-/"); } } while (false); | ||||||||
2321 | |||||||||
2322 | if ( pStyleSheet ) | ||||||||
2323 | pStyleSet = &pStyleSheet->GetItemSet(); | ||||||||
2324 | else | ||||||||
2325 | rbHeader = rbFooter = false; | ||||||||
2326 | } | ||||||||
2327 | |||||||||
2328 | OSL_ENSURE( pStyleSet, "PageStyle-Set not found! :-(" )do { if (true && (!(pStyleSet))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/ui/docshell/docsh4.cxx" ":" "2328" ": "), "%s", "PageStyle-Set not found! :-("); } } while (false); | ||||||||
2329 | if (!pStyleSet) | ||||||||
2330 | return; | ||||||||
2331 | |||||||||
2332 | const SvxSetItem* pSetItem = nullptr; | ||||||||
2333 | const SfxItemSet* pSet = nullptr; | ||||||||
2334 | |||||||||
2335 | pSetItem = &pStyleSet->Get( ATTR_PAGE_HEADERSET ); | ||||||||
2336 | pSet = &pSetItem->GetItemSet(); | ||||||||
2337 | rbHeader = pSet->Get(ATTR_PAGE_ON).GetValue(); | ||||||||
2338 | |||||||||
2339 | pSetItem = &pStyleSet->Get( ATTR_PAGE_FOOTERSET ); | ||||||||
2340 | pSet = &pSetItem->GetItemSet(); | ||||||||
2341 | rbFooter = pSet->Get(ATTR_PAGE_ON).GetValue(); | ||||||||
2342 | } | ||||||||
2343 | |||||||||
2344 | #if defined(_WIN32) | ||||||||
2345 | bool ScDocShell::DdeGetData( const OUString& rItem, | ||||||||
2346 | const OUString& rMimeType, | ||||||||
2347 | css::uno::Any & rValue ) | ||||||||
2348 | { | ||||||||
2349 | SotClipboardFormatId eFormatId = SotExchange::GetFormatIdFromMimeType( rMimeType ); | ||||||||
2350 | if (SotClipboardFormatId::STRING == eFormatId || SotClipboardFormatId::STRING_TSVC == eFormatId) | ||||||||
2351 | { | ||||||||
2352 | if( rItem.equalsIgnoreAsciiCase( "Format" ) ) | ||||||||
2353 | { | ||||||||
2354 | OString aFmtByte(OUStringToOString(m_aDdeTextFmt, | ||||||||
2355 | osl_getThreadTextEncoding())); | ||||||||
2356 | rValue <<= css::uno::Sequence< sal_Int8 >( | ||||||||
2357 | reinterpret_cast<const sal_Int8*>(aFmtByte.getStr()), | ||||||||
2358 | aFmtByte.getLength() + 1 ); | ||||||||
2359 | return true; | ||||||||
2360 | } | ||||||||
2361 | ScImportExport aObj( m_aDocument, rItem ); | ||||||||
2362 | if ( !aObj.IsRef() ) | ||||||||
2363 | return false; // invalid range | ||||||||
2364 | |||||||||
2365 | if( m_aDdeTextFmt[0] == 'F' ) | ||||||||
2366 | aObj.SetFormulas( true ); | ||||||||
2367 | if( m_aDdeTextFmt == "SYLK" || | ||||||||
2368 | m_aDdeTextFmt == "FSYLK" ) | ||||||||
2369 | { | ||||||||
2370 | OString aData; | ||||||||
2371 | if( aObj.ExportByteString( aData, osl_getThreadTextEncoding(), | ||||||||
2372 | SotClipboardFormatId::SYLK ) ) | ||||||||
2373 | { | ||||||||
2374 | rValue <<= css::uno::Sequence< sal_Int8 >( | ||||||||
2375 | reinterpret_cast<const sal_Int8*>(aData.getStr()), | ||||||||
2376 | aData.getLength() + 1 ); | ||||||||
2377 | return true; | ||||||||
2378 | } | ||||||||
2379 | else | ||||||||
2380 | return false; | ||||||||
2381 | } | ||||||||
2382 | if( m_aDdeTextFmt == "CSV" || | ||||||||
2383 | m_aDdeTextFmt == "FCSV" ) | ||||||||
2384 | aObj.SetSeparator( ',' ); | ||||||||
2385 | aObj.SetExportTextOptions( ScExportTextOptions( ScExportTextOptions::ToSpace, 0, false ) ); | ||||||||
2386 | return aObj.ExportData( rMimeType, rValue ); | ||||||||
2387 | } | ||||||||
2388 | |||||||||
2389 | ScImportExport aObj( m_aDocument, rItem ); | ||||||||
2390 | aObj.SetExportTextOptions( ScExportTextOptions( ScExportTextOptions::ToSpace, 0, false ) ); | ||||||||
2391 | return aObj.IsRef() && aObj.ExportData( rMimeType, rValue ); | ||||||||
2392 | } | ||||||||
2393 | |||||||||
2394 | bool ScDocShell::DdeSetData( const OUString& rItem, | ||||||||
2395 | const OUString& rMimeType, | ||||||||
2396 | const css::uno::Any & rValue ) | ||||||||
2397 | { | ||||||||
2398 | SotClipboardFormatId eFormatId = SotExchange::GetFormatIdFromMimeType( rMimeType ); | ||||||||
2399 | if (SotClipboardFormatId::STRING == eFormatId || SotClipboardFormatId::STRING_TSVC == eFormatId) | ||||||||
2400 | { | ||||||||
2401 | if( rItem.equalsIgnoreAsciiCase( "Format" ) ) | ||||||||
2402 | { | ||||||||
2403 | if ( ScByteSequenceToString::GetString( m_aDdeTextFmt, rValue, osl_getThreadTextEncoding() ) ) | ||||||||
2404 | { | ||||||||
2405 | m_aDdeTextFmt = m_aDdeTextFmt.toAsciiUpperCase(); | ||||||||
2406 | return true; | ||||||||
2407 | } | ||||||||
2408 | return false; | ||||||||
2409 | } | ||||||||
2410 | ScImportExport aObj( m_aDocument, rItem ); | ||||||||
2411 | if( m_aDdeTextFmt[0] == 'F' ) | ||||||||
2412 | aObj.SetFormulas( true ); | ||||||||
2413 | if( m_aDdeTextFmt == "SYLK" || | ||||||||
2414 | m_aDdeTextFmt == "FSYLK" ) | ||||||||
2415 | { | ||||||||
2416 | OUString aData; | ||||||||
2417 | if ( ScByteSequenceToString::GetString( aData, rValue, osl_getThreadTextEncoding() ) ) | ||||||||
2418 | { | ||||||||
2419 | return aObj.ImportString( aData, SotClipboardFormatId::SYLK ); | ||||||||
2420 | } | ||||||||
2421 | return false; | ||||||||
2422 | } | ||||||||
2423 | if( m_aDdeTextFmt == "CSV" || | ||||||||
2424 | m_aDdeTextFmt == "FCSV" ) | ||||||||
2425 | aObj.SetSeparator( ',' ); | ||||||||
2426 | OSL_ENSURE( false, "Implementation is missing" )do { if (true && (!(false))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/ui/docshell/docsh4.cxx" ":" "2426" ": "), "%s", "Implementation is missing"); } } while (false); | ||||||||
2427 | return false; | ||||||||
2428 | } | ||||||||
2429 | /*ScImportExport aObj( aDocument, rItem ); | ||||||||
2430 | return aObj.IsRef() && ScImportExport::ImportData( rMimeType, rValue );*/ | ||||||||
2431 | OSL_ENSURE( false, "Implementation is missing" )do { if (true && (!(false))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/ui/docshell/docsh4.cxx" ":" "2431" ": "), "%s", "Implementation is missing"); } } while (false); | ||||||||
2432 | return false; | ||||||||
2433 | } | ||||||||
2434 | #endif | ||||||||
2435 | |||||||||
2436 | ::sfx2::SvLinkSource* ScDocShell::DdeCreateLinkSource( const OUString& rItem ) | ||||||||
2437 | { | ||||||||
2438 | // only check for valid item string - range is parsed again in ScServerObject ctor | ||||||||
2439 | |||||||||
2440 | // named range? | ||||||||
2441 | OUString aPos = rItem; | ||||||||
2442 | ScRangeName* pRange = m_aDocument.GetRangeName(); | ||||||||
2443 | if( pRange ) | ||||||||
2444 | { | ||||||||
2445 | const ScRangeData* pData = pRange->findByUpperName(ScGlobal::getCharClassPtr()->uppercase(aPos)); | ||||||||
2446 | if (pData) | ||||||||
2447 | { | ||||||||
2448 | if( pData->HasType( ScRangeData::Type::RefArea ) | ||||||||
2449 | || pData->HasType( ScRangeData::Type::AbsArea ) | ||||||||
2450 | || pData->HasType( ScRangeData::Type::AbsPos ) ) | ||||||||
2451 | pData->GetSymbol( aPos ); // continue with the name's contents | ||||||||
2452 | } | ||||||||
2453 | } | ||||||||
2454 | |||||||||
2455 | // Address in DDE function must be always parsed as CONV_OOO so that it | ||||||||
2456 | // would always work regardless of current address conversion. We do this | ||||||||
2457 | // because the address item in a DDE entry is *not* normalized when saved | ||||||||
2458 | // into ODF. | ||||||||
2459 | ScRange aRange; | ||||||||
2460 | bool bValid = ( (aRange.Parse(aPos, m_aDocument, formula::FormulaGrammar::CONV_OOO ) & ScRefFlags::VALID) || | ||||||||
2461 | (aRange.aStart.Parse(aPos, m_aDocument, formula::FormulaGrammar::CONV_OOO) & ScRefFlags::VALID) ); | ||||||||
2462 | |||||||||
2463 | ScServerObject* pObj = nullptr; // NULL = error | ||||||||
2464 | if ( bValid ) | ||||||||
2465 | pObj = new ScServerObject( this, rItem ); | ||||||||
2466 | |||||||||
2467 | // GetLinkManager()->InsertServer() is in the ScServerObject ctor | ||||||||
2468 | |||||||||
2469 | return pObj; | ||||||||
2470 | } | ||||||||
2471 | |||||||||
2472 | void ScDocShell::LOKCommentNotify(LOKCommentNotificationType nType, const ScDocument* pDocument, const ScAddress& rPos, const ScPostIt* pNote) | ||||||||
2473 | { | ||||||||
2474 | if ( !pDocument->IsDocVisible() || // don't want callbacks until document load | ||||||||
2475 | !comphelper::LibreOfficeKit::isActive() || | ||||||||
2476 | comphelper::LibreOfficeKit::isTiledAnnotations() ) | ||||||||
2477 | return; | ||||||||
2478 | |||||||||
2479 | boost::property_tree::ptree aAnnotation; | ||||||||
2480 | aAnnotation.put("action", (nType == LOKCommentNotificationType::Add ? "Add" : | ||||||||
2481 | (nType == LOKCommentNotificationType::Remove ? "Remove" : | ||||||||
2482 | (nType == LOKCommentNotificationType::Modify ? "Modify" : "???")))); | ||||||||
2483 | |||||||||
2484 | assert(pNote)(static_cast <bool> (pNote) ? void (0) : __assert_fail ( "pNote", "/home/maarten/src/libreoffice/core/sc/source/ui/docshell/docsh4.cxx" , 2484, __extension__ __PRETTY_FUNCTION__)); | ||||||||
2485 | aAnnotation.put("id", pNote->GetId()); | ||||||||
2486 | aAnnotation.put("tab", rPos.Tab()); | ||||||||
2487 | |||||||||
2488 | if (nType != LOKCommentNotificationType::Remove) | ||||||||
2489 | { | ||||||||
2490 | aAnnotation.put("author", pNote->GetAuthor()); | ||||||||
2491 | aAnnotation.put("dateTime", pNote->GetDate()); | ||||||||
2492 | aAnnotation.put("text", pNote->GetText()); | ||||||||
2493 | |||||||||
2494 | // Calculating the cell cursor position | ||||||||
2495 | ScViewData* pViewData = GetViewData(); | ||||||||
2496 | if (pViewData && pViewData->GetActiveWin()) | ||||||||
2497 | { | ||||||||
2498 | bool bInPrintTwips = comphelper::LibreOfficeKit::isCompatFlagSet( | ||||||||
2499 | comphelper::LibreOfficeKit::Compat::scPrintTwipsMsgs); | ||||||||
2500 | OString aRectString; | ||||||||
2501 | if (bInPrintTwips) | ||||||||
2502 | { | ||||||||
2503 | Point aTopLeft = pViewData->GetPrintTwipsPos(rPos.Col(), rPos.Row()); | ||||||||
2504 | long nSizeX, nSizeY; | ||||||||
2505 | pViewData->GetMergeSizePrintTwips(rPos.Col(), rPos.Row(), nSizeX, nSizeY); | ||||||||
2506 | aRectString = tools::Rectangle(aTopLeft, Size(nSizeX - 1, nSizeY - 1)).toString(); | ||||||||
2507 | } | ||||||||
2508 | else | ||||||||
2509 | { | ||||||||
2510 | Point aTopLeft = pViewData->GetScrPos(rPos.Col(), rPos.Row(), | ||||||||
2511 | pViewData->GetActivePart(), true); | ||||||||
2512 | long nSizeXPix, nSizeYPix; | ||||||||
2513 | pViewData->GetMergeSizePixel(rPos.Col(), rPos.Row(), nSizeXPix, nSizeYPix); | ||||||||
2514 | const double fPPTX = pViewData->GetPPTX(); | ||||||||
2515 | const double fPPTY = pViewData->GetPPTY(); | ||||||||
2516 | aRectString = tools::Rectangle(Point(aTopLeft.getX() / fPPTX, aTopLeft.getY() / fPPTY), | ||||||||
2517 | Size(nSizeXPix / fPPTX, nSizeYPix / fPPTY)).toString(); | ||||||||
2518 | } | ||||||||
2519 | aAnnotation.put("cellPos", aRectString); | ||||||||
2520 | } | ||||||||
2521 | } | ||||||||
2522 | |||||||||
2523 | boost::property_tree::ptree aTree; | ||||||||
2524 | aTree.add_child("comment", aAnnotation); | ||||||||
2525 | std::stringstream aStream; | ||||||||
2526 | boost::property_tree::write_json(aStream, aTree); | ||||||||
2527 | std::string aPayload = aStream.str(); | ||||||||
2528 | |||||||||
2529 | ScViewData* pViewData = GetViewData(); | ||||||||
2530 | SfxViewShell* pThisViewShell = ( pViewData ? pViewData->GetViewShell() : nullptr ); | ||||||||
2531 | SfxViewShell* pViewShell = SfxViewShell::GetFirst(); | ||||||||
2532 | while (pViewShell) | ||||||||
2533 | { | ||||||||
2534 | if (pThisViewShell == nullptr || pViewShell->GetDocId() == pThisViewShell->GetDocId()) | ||||||||
2535 | pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_COMMENT, aPayload.c_str()); | ||||||||
2536 | pViewShell = SfxViewShell::GetNext(*pViewShell); | ||||||||
2537 | } | ||||||||
2538 | } | ||||||||
2539 | |||||||||
2540 | ScViewData* ScDocShell::GetViewData() | ||||||||
2541 | { | ||||||||
2542 | SfxViewShell* pCur = SfxViewShell::Current(); | ||||||||
2543 | ScTabViewShell* pViewSh = dynamic_cast< ScTabViewShell *>( pCur ); | ||||||||
2544 | return pViewSh ? &pViewSh->GetViewData() : nullptr; | ||||||||
2545 | } | ||||||||
2546 | |||||||||
2547 | SCTAB ScDocShell::GetCurTab() | ||||||||
2548 | { | ||||||||
2549 | //! this must be made non-static and use a ViewShell from this document! | ||||||||
2550 | |||||||||
2551 | ScViewData* pViewData = GetViewData(); | ||||||||
2552 | |||||||||
2553 | return pViewData ? pViewData->GetTabNo() : static_cast<SCTAB>(0); | ||||||||
2554 | } | ||||||||
2555 | |||||||||
2556 | ScTabViewShell* ScDocShell::GetBestViewShell( bool bOnlyVisible ) | ||||||||
2557 | { | ||||||||
2558 | ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell(); | ||||||||
2559 | // wrong Doc? | ||||||||
2560 | if( pViewSh && pViewSh->GetViewData().GetDocShell() != this ) | ||||||||
2561 | pViewSh = nullptr; | ||||||||
2562 | if( !pViewSh ) | ||||||||
2563 | { | ||||||||
2564 | // 1. find ViewShell | ||||||||
2565 | SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this, bOnlyVisible ); | ||||||||
2566 | if( pFrame ) | ||||||||
2567 | { | ||||||||
2568 | SfxViewShell* p = pFrame->GetViewShell(); | ||||||||
2569 | pViewSh = dynamic_cast< ScTabViewShell *>( p ); | ||||||||
2570 | } | ||||||||
2571 | } | ||||||||
2572 | return pViewSh; | ||||||||
2573 | } | ||||||||
2574 | |||||||||
2575 | SfxBindings* ScDocShell::GetViewBindings() | ||||||||
2576 | { | ||||||||
2577 | // used to invalidate slots after changes to this document | ||||||||
2578 | |||||||||
2579 | SfxViewShell* pViewSh = GetBestViewShell(); | ||||||||
2580 | if (pViewSh) | ||||||||
2581 | return &pViewSh->GetViewFrame()->GetBindings(); | ||||||||
2582 | else | ||||||||
2583 | return nullptr; | ||||||||
2584 | } | ||||||||
2585 | |||||||||
2586 | ScDocShell* ScDocShell::GetShellByNum( sal_uInt16 nDocNo ) // static | ||||||||
2587 | { | ||||||||
2588 | ScDocShell* pFound = nullptr; | ||||||||
2589 | SfxObjectShell* pShell = SfxObjectShell::GetFirst(); | ||||||||
2590 | sal_uInt16 nShellCnt = 0; | ||||||||
2591 | |||||||||
2592 | while ( pShell && !pFound ) | ||||||||
2593 | { | ||||||||
2594 | if ( dynamic_cast<const ScDocShell*>(pShell) != nullptr ) | ||||||||
2595 | { | ||||||||
2596 | if ( nShellCnt == nDocNo ) | ||||||||
2597 | pFound = static_cast<ScDocShell*>(pShell); | ||||||||
2598 | else | ||||||||
2599 | ++nShellCnt; | ||||||||
2600 | } | ||||||||
2601 | pShell = SfxObjectShell::GetNext( *pShell ); | ||||||||
2602 | } | ||||||||
2603 | |||||||||
2604 | return pFound; | ||||||||
2605 | } | ||||||||
2606 | |||||||||
2607 | IMPL_LINK( ScDocShell, DialogClosedHdl, sfx2::FileDialogHelper*, _pFileDlg, void )void ScDocShell::LinkStubDialogClosedHdl(void * instance, sfx2 ::FileDialogHelper* data) { return static_cast<ScDocShell * >(instance)->DialogClosedHdl(data); } void ScDocShell:: DialogClosedHdl(sfx2::FileDialogHelper* _pFileDlg) | ||||||||
2608 | { | ||||||||
2609 | OSL_ENSURE( _pFileDlg, "ScDocShell::DialogClosedHdl(): no file dialog" )do { if (true && (!(_pFileDlg))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/ui/docshell/docsh4.cxx" ":" "2609" ": "), "%s", "ScDocShell::DialogClosedHdl(): no file dialog" ); } } while (false); | ||||||||
2610 | OSL_ENSURE( m_pImpl->pDocInserter, "ScDocShell::DialogClosedHdl(): no document inserter" )do { if (true && (!(m_pImpl->pDocInserter))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/ui/docshell/docsh4.cxx" ":" "2610" ": "), "%s", "ScDocShell::DialogClosedHdl(): no document inserter" ); } } while (false); | ||||||||
2611 | |||||||||
2612 | if ( ERRCODE_NONEErrCode(0) == _pFileDlg->GetError() ) | ||||||||
2613 | { | ||||||||
2614 | sal_uInt16 nSlot = m_pImpl->pRequest->GetSlot(); | ||||||||
2615 | std::unique_ptr<SfxMedium> pMed = m_pImpl->pDocInserter->CreateMedium(); | ||||||||
2616 | // #i87094# If a .odt was selected pMed is NULL. | ||||||||
2617 | if (pMed) | ||||||||
2618 | { | ||||||||
2619 | m_pImpl->pRequest->AppendItem( SfxStringItem( SID_FILE_NAME(5000 + 507), pMed->GetName() ) ); | ||||||||
2620 | if ( SID_DOCUMENT_COMPARE(5000 + 1586) == nSlot ) | ||||||||
2621 | { | ||||||||
2622 | if ( pMed->GetFilter() ) | ||||||||
2623 | m_pImpl->pRequest->AppendItem( | ||||||||
2624 | SfxStringItem( SID_FILTER_NAME(5000 + 530), pMed->GetFilter()->GetFilterName() ) ); | ||||||||
2625 | OUString sOptions = ScDocumentLoader::GetOptions( *pMed ); | ||||||||
2626 | if ( !sOptions.isEmpty() ) | ||||||||
2627 | m_pImpl->pRequest->AppendItem( SfxStringItem( SID_FILE_FILTEROPTIONS(5000 + 527), sOptions ) ); | ||||||||
2628 | } | ||||||||
2629 | const SfxPoolItem* pItem = nullptr; | ||||||||
2630 | const SfxInt16Item* pInt16Item(nullptr); | ||||||||
2631 | SfxItemSet* pSet = pMed->GetItemSet(); | ||||||||
2632 | if (pSet && pSet->GetItemState(SID_VERSION(5000 + 1583), true, &pItem) == SfxItemState::SET) | ||||||||
2633 | { | ||||||||
2634 | pInt16Item = dynamic_cast<const SfxInt16Item*>(pItem); | ||||||||
2635 | } | ||||||||
2636 | if (pInt16Item) | ||||||||
2637 | { | ||||||||
2638 | m_pImpl->pRequest->AppendItem( *pItem ); | ||||||||
2639 | } | ||||||||
2640 | |||||||||
2641 | Execute( *(m_pImpl->pRequest) ); | ||||||||
2642 | } | ||||||||
2643 | } | ||||||||
2644 | |||||||||
2645 | m_pImpl->bIgnoreLostRedliningWarning = false; | ||||||||
2646 | } | ||||||||
2647 | |||||||||
2648 | #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT1 | ||||||||
2649 | |||||||||
2650 | void ScDocShell::EnableSharedSettings( bool bEnable ) | ||||||||
2651 | { | ||||||||
2652 | SetDocumentModified(); | ||||||||
2653 | |||||||||
2654 | if ( bEnable ) | ||||||||
2655 | { | ||||||||
2656 | m_aDocument.EndChangeTracking(); | ||||||||
2657 | m_aDocument.StartChangeTracking(); | ||||||||
2658 | |||||||||
2659 | // hide accept or reject changes dialog | ||||||||
2660 | sal_uInt16 nId = ScAcceptChgDlgWrapper::GetChildWindowId(); | ||||||||
2661 | SfxViewFrame* pViewFrame = SfxViewFrame::Current(); | ||||||||
2662 | if ( pViewFrame && pViewFrame->HasChildWindow( nId ) ) | ||||||||
2663 | { | ||||||||
2664 | pViewFrame->ToggleChildWindow( nId ); | ||||||||
2665 | SfxBindings* pBindings = GetViewBindings(); | ||||||||
2666 | if ( pBindings ) | ||||||||
2667 | { | ||||||||
2668 | pBindings->Invalidate( FID_CHG_ACCEPT((((((26000 + 200) + 20)) + 20)) + 18) ); | ||||||||
2669 | } | ||||||||
2670 | } | ||||||||
2671 | } | ||||||||
2672 | else | ||||||||
2673 | { | ||||||||
2674 | m_aDocument.EndChangeTracking(); | ||||||||
2675 | } | ||||||||
2676 | |||||||||
2677 | ScChangeViewSettings aChangeViewSet; | ||||||||
2678 | aChangeViewSet.SetShowChanges( false ); | ||||||||
2679 | m_aDocument.SetChangeViewSettings( aChangeViewSet ); | ||||||||
2680 | } | ||||||||
2681 | |||||||||
2682 | uno::Reference< frame::XModel > ScDocShell::LoadSharedDocument() | ||||||||
2683 | { | ||||||||
2684 | uno::Reference< frame::XModel > xModel; | ||||||||
2685 | try | ||||||||
2686 | { | ||||||||
2687 | SC_MOD()( static_cast<ScModule*>(SfxApplication::GetModule(SfxToolsModule ::Calc)) )->SetInSharedDocLoading( true ); | ||||||||
2688 | uno::Reference< frame::XDesktop2 > xLoader = frame::Desktop::create( ::comphelper::getProcessComponentContext() ); | ||||||||
2689 | uno::Sequence < beans::PropertyValue > aArgs( 1 ); | ||||||||
2690 | aArgs[0].Name = "Hidden"; | ||||||||
2691 | aArgs[0].Value <<= true; | ||||||||
2692 | |||||||||
2693 | if ( GetMedium() ) | ||||||||
2694 | { | ||||||||
2695 | const SfxStringItem* pPasswordItem = SfxItemSet::GetItem<SfxStringItem>(GetMedium()->GetItemSet(), SID_PASSWORD(((((10000 + 1499) + 1) + 499) + 1) + 36), false); | ||||||||
2696 | if ( pPasswordItem && !pPasswordItem->GetValue().isEmpty() ) | ||||||||
2697 | { | ||||||||
2698 | aArgs.realloc( 2 ); | ||||||||
2699 | aArgs[1].Name = "Password"; | ||||||||
2700 | aArgs[1].Value <<= pPasswordItem->GetValue(); | ||||||||
2701 | } | ||||||||
2702 | const SfxUnoAnyItem* pEncryptionItem = SfxItemSet::GetItem<SfxUnoAnyItem>(GetMedium()->GetItemSet(), SID_ENCRYPTIONDATA(5000 + 1722), false); | ||||||||
2703 | if (pEncryptionItem) | ||||||||
2704 | { | ||||||||
2705 | aArgs.realloc(aArgs.getLength() + 1); | ||||||||
2706 | aArgs[aArgs.getLength() - 1].Name = "EncryptionData"; | ||||||||
2707 | aArgs[aArgs.getLength() - 1].Value = pEncryptionItem->GetValue(); | ||||||||
2708 | } | ||||||||
2709 | } | ||||||||
2710 | |||||||||
2711 | xModel.set( | ||||||||
2712 | xLoader->loadComponentFromURL( GetSharedFileURL(), "_blank", 0, aArgs ), | ||||||||
2713 | uno::UNO_QUERY_THROW ); | ||||||||
2714 | SC_MOD()( static_cast<ScModule*>(SfxApplication::GetModule(SfxToolsModule ::Calc)) )->SetInSharedDocLoading( false ); | ||||||||
2715 | } | ||||||||
2716 | catch ( uno::Exception& ) | ||||||||
2717 | { | ||||||||
2718 | OSL_FAIL( "ScDocShell::LoadSharedDocument(): 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/docsh4.cxx" ":" "2718" ": "), "%s", "ScDocShell::LoadSharedDocument(): caught exception" ); } } while (false); | ||||||||
2719 | SC_MOD()( static_cast<ScModule*>(SfxApplication::GetModule(SfxToolsModule ::Calc)) )->SetInSharedDocLoading( false ); | ||||||||
2720 | try | ||||||||
2721 | { | ||||||||
2722 | uno::Reference< util::XCloseable > xClose( xModel, uno::UNO_QUERY_THROW ); | ||||||||
2723 | xClose->close( true ); | ||||||||
2724 | return uno::Reference< frame::XModel >(); | ||||||||
2725 | } | ||||||||
2726 | catch ( uno::Exception& ) | ||||||||
2727 | { | ||||||||
2728 | return uno::Reference< frame::XModel >(); | ||||||||
2729 | } | ||||||||
2730 | } | ||||||||
2731 | return xModel; | ||||||||
2732 | } | ||||||||
2733 | |||||||||
2734 | #endif | ||||||||
2735 | |||||||||
2736 | /* 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 |