Bug Summary

File:home/maarten/src/libreoffice/core/include/rtl/ref.hxx
Warning:line 192, column 9
Use of memory after it is freed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name viewsh.cxx -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -isystem /usr/include/libxml2 -D BOOST_ERROR_CODE_HEADER_ONLY -D BOOST_SYSTEM_NO_DEPRECATED -D CPPU_ENV=gcc3 -D LINUX -D OSL_DEBUG_LEVEL=1 -D SAL_LOG_INFO -D SAL_LOG_WARN -D UNIX -D UNX -D X86_64 -D _PTHREADS -D _REENTRANT -D SFX2_DLLIMPLEMENTATION -D ENABLE_CUPS -D SYSTEM_LIBXML -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/liborcus/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/liborcus/include -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/sfx2/inc -I /home/maarten/src/libreoffice/core/sfx2/source/inc -I /home/maarten/src/libreoffice/core/workdir/SdiTarget/sfx2/sdi -I /home/maarten/src/libreoffice/core/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include/linux -I /home/maarten/src/libreoffice/core/config_host -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/officecfg/registry -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-missing-braces -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/maarten/src/libreoffice/core -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c++ /home/maarten/src/libreoffice/core/sfx2/source/view/viewsh.cxx

/home/maarten/src/libreoffice/core/sfx2/source/view/viewsh.cxx

1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
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 <sal/log.hxx>
23#include <svl/stritem.hxx>
24#include <svl/eitem.hxx>
25#include <svl/whiter.hxx>
26#include <vcl/toolbox.hxx>
27#include <vcl/svapp.hxx>
28#include <vcl/weld.hxx>
29#include <svl/intitem.hxx>
30#include <svtools/langhelp.hxx>
31#include <com/sun/star/frame/XLayoutManager.hpp>
32#include <com/sun/star/frame/ModuleManager.hpp>
33#include <com/sun/star/io/IOException.hpp>
34#include <com/sun/star/beans/XPropertySet.hpp>
35#include <com/sun/star/embed/EmbedStates.hpp>
36#include <com/sun/star/embed/EmbedMisc.hpp>
37#include <com/sun/star/embed/XEmbeddedObject.hpp>
38#include <com/sun/star/container/XContainerQuery.hpp>
39#include <com/sun/star/frame/XStorable.hpp>
40#include <com/sun/star/frame/XModel.hpp>
41#include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
42#include <com/sun/star/lang/XMultiServiceFactory.hpp>
43#include <com/sun/star/datatransfer/clipboard/XClipboardListener.hpp>
44#include <com/sun/star/datatransfer/clipboard/XClipboardNotifier.hpp>
45#include <com/sun/star/view/XRenderable.hpp>
46#include <com/sun/star/uno/Reference.hxx>
47#include <cppuhelper/implbase.hxx>
48
49#include <tools/diagnose_ex.h>
50#include <tools/urlobj.hxx>
51#include <unotools/tempfile.hxx>
52#include <svtools/soerr.hxx>
53#include <tools/svborder.hxx>
54
55#include <framework/actiontriggerhelper.hxx>
56#include <comphelper/lok.hxx>
57#include <comphelper/namedvaluecollection.hxx>
58#include <comphelper/processfactory.hxx>
59#include <comphelper/sequenceashashmap.hxx>
60#include <toolkit/helper/vclunohelper.hxx>
61#include <vcl/settings.hxx>
62#include <vcl/commandinfoprovider.hxx>
63#include <LibreOfficeKit/LibreOfficeKitEnums.h>
64
65#include <officecfg/Office/Common.hxx>
66#include <officecfg/Setup.hxx>
67#include <sfx2/app.hxx>
68#include <sfx2/flatpak.hxx>
69#include <sfx2/viewsh.hxx>
70#include "viewimp.hxx"
71#include <sfx2/sfxresid.hxx>
72#include <sfx2/request.hxx>
73#include <sfx2/printer.hxx>
74#include <sfx2/docfile.hxx>
75#include <sfx2/dispatch.hxx>
76#include <sfx2/strings.hrc>
77#include <sfx2/sfxbasecontroller.hxx>
78#include <sfx2/mailmodelapi.hxx>
79#include <bluthsndapi.hxx>
80#include <sfx2/viewfrm.hxx>
81#include <sfx2/event.hxx>
82#include <sfx2/ipclient.hxx>
83#include <sfx2/sfxsids.hrc>
84#include <sfx2/objface.hxx>
85#include <sfx2/lokhelper.hxx>
86#include <openuriexternally.hxx>
87#include <shellimpl.hxx>
88
89#include <vector>
90#include <libxml/xmlwriter.h>
91
92using namespace ::com::sun::star;
93using namespace ::com::sun::star::uno;
94using namespace ::com::sun::star::frame;
95using namespace ::com::sun::star::beans;
96using namespace ::com::sun::star::util;
97using namespace ::cppu;
98
99#define ShellClass_SfxViewShell
100#include <sfxslots.hxx>
101
102
103class SfxClipboardChangeListener : public ::cppu::WeakImplHelper<
104 datatransfer::clipboard::XClipboardListener >
105{
106public:
107 SfxClipboardChangeListener( SfxViewShell* pView, const uno::Reference< datatransfer::clipboard::XClipboardNotifier >& xClpbrdNtfr );
108
109 // XEventListener
110 virtual void SAL_CALL disposing( const lang::EventObject& rEventObject ) override;
111
112 // XClipboardListener
113 virtual void SAL_CALL changedContents( const datatransfer::clipboard::ClipboardEvent& rEventObject ) override;
114
115 void DisconnectViewShell() { m_pViewShell = nullptr; }
116 void ChangedContents();
117
118 enum AsyncExecuteCmd
119 {
120 ASYNCEXECUTE_CMD_DISPOSING,
121 ASYNCEXECUTE_CMD_CHANGEDCONTENTS
122 };
123
124 struct AsyncExecuteInfo
125 {
126 AsyncExecuteInfo( AsyncExecuteCmd eCmd, SfxClipboardChangeListener* pListener ) :
127 m_eCmd( eCmd ), m_xListener( pListener ) {}
128
129 AsyncExecuteCmd m_eCmd;
130 rtl::Reference<SfxClipboardChangeListener> m_xListener;
131 };
132
133private:
134 SfxViewShell* m_pViewShell;
135 uno::Reference< datatransfer::clipboard::XClipboardNotifier > m_xClpbrdNtfr;
136 uno::Reference< lang::XComponent > m_xCtrl;
137
138 DECL_STATIC_LINK( SfxClipboardChangeListener, AsyncExecuteHdl_Impl, void*, void )static void LinkStubAsyncExecuteHdl_Impl(void *, void*); static
void AsyncExecuteHdl_Impl(SfxClipboardChangeListener *, void
*)
;
139};
140
141SfxClipboardChangeListener::SfxClipboardChangeListener( SfxViewShell* pView, const uno::Reference< datatransfer::clipboard::XClipboardNotifier >& xClpbrdNtfr )
142 : m_pViewShell( nullptr ), m_xClpbrdNtfr( xClpbrdNtfr ), m_xCtrl(pView->GetController())
143{
144 if ( m_xCtrl.is() )
145 {
146 m_xCtrl->addEventListener( uno::Reference < lang::XEventListener > ( static_cast < lang::XEventListener* >( this ) ) );
147 m_pViewShell = pView;
148 }
149 if ( m_xClpbrdNtfr.is() )
150 {
151 m_xClpbrdNtfr->addClipboardListener( uno::Reference< datatransfer::clipboard::XClipboardListener >(
152 static_cast< datatransfer::clipboard::XClipboardListener* >( this )));
153 }
154}
155
156void SfxClipboardChangeListener::ChangedContents()
157{
158 const SolarMutexGuard aGuard;
159 if (!m_pViewShell)
160 return;
161
162 SfxBindings& rBind = m_pViewShell->GetViewFrame()->GetBindings();
163 rBind.Invalidate(SID_PASTE(5000 + 712));
164 rBind.Invalidate(SID_PASTE_SPECIAL(5000 + 311));
165 rBind.Invalidate(SID_CLIPBOARD_FORMAT_ITEMS(5000 + 312));
166
167 if (comphelper::LibreOfficeKit::isActive())
168 {
169 // In the future we might send the payload as well.
170 SfxLokHelper::notifyAllViews(LOK_CALLBACK_CLIPBOARD_CHANGED, "");
171 }
172}
173
174IMPL_STATIC_LINK( SfxClipboardChangeListener, AsyncExecuteHdl_Impl, void*, p, void )void SfxClipboardChangeListener::LinkStubAsyncExecuteHdl_Impl
(void * instance, void* data) { return AsyncExecuteHdl_Impl(static_cast
<SfxClipboardChangeListener *>(instance), data); } void
SfxClipboardChangeListener::AsyncExecuteHdl_Impl(__attribute__
((unused)) SfxClipboardChangeListener *, void* p)
175{
176 AsyncExecuteInfo* pAsyncExecuteInfo = static_cast<AsyncExecuteInfo*>(p);
177 if ( pAsyncExecuteInfo )
178 {
179 if ( pAsyncExecuteInfo->m_xListener.is() )
180 {
181 if ( pAsyncExecuteInfo->m_eCmd == ASYNCEXECUTE_CMD_DISPOSING )
182 pAsyncExecuteInfo->m_xListener->DisconnectViewShell();
183 else if ( pAsyncExecuteInfo->m_eCmd == ASYNCEXECUTE_CMD_CHANGEDCONTENTS )
184 pAsyncExecuteInfo->m_xListener->ChangedContents();
185 }
186 }
187 delete pAsyncExecuteInfo;
188}
189
190void SAL_CALL SfxClipboardChangeListener::disposing( const lang::EventObject& /*rEventObject*/ )
191{
192 // Either clipboard or ViewShell is going to be destroyed -> no interest in listening anymore
193 uno::Reference< lang::XComponent > xCtrl( m_xCtrl );
194 uno::Reference< datatransfer::clipboard::XClipboardNotifier > xNotify( m_xClpbrdNtfr );
195
196 uno::Reference< datatransfer::clipboard::XClipboardListener > xThis( static_cast< datatransfer::clipboard::XClipboardListener* >( this ));
197 if ( xCtrl.is() )
198 xCtrl->removeEventListener( uno::Reference < lang::XEventListener > ( static_cast < lang::XEventListener* >( this )));
199 if ( xNotify.is() )
200 xNotify->removeClipboardListener( xThis );
201
202 // Make asynchronous call to avoid locking SolarMutex which is the
203 // root for many deadlocks, especially in conjunction with the "Windows"
204 // based single thread apartment clipboard code!
205 AsyncExecuteInfo* pInfo = new AsyncExecuteInfo( ASYNCEXECUTE_CMD_DISPOSING, this );
206 Application::PostUserEvent( LINK( nullptr, SfxClipboardChangeListener, AsyncExecuteHdl_Impl )::tools::detail::makeLink( ::tools::detail::castTo<SfxClipboardChangeListener
*>(nullptr), &SfxClipboardChangeListener::LinkStubAsyncExecuteHdl_Impl
)
, pInfo );
207}
208
209void SAL_CALL SfxClipboardChangeListener::changedContents( const datatransfer::clipboard::ClipboardEvent& )
210{
211 // Make asynchronous call to avoid locking SolarMutex which is the
212 // root for many deadlocks, especially in conjunction with the "Windows"
213 // based single thread apartment clipboard code!
214 AsyncExecuteInfo* pInfo = new AsyncExecuteInfo( ASYNCEXECUTE_CMD_CHANGEDCONTENTS, this );
215 Application::PostUserEvent( LINK( nullptr, SfxClipboardChangeListener, AsyncExecuteHdl_Impl )::tools::detail::makeLink( ::tools::detail::castTo<SfxClipboardChangeListener
*>(nullptr), &SfxClipboardChangeListener::LinkStubAsyncExecuteHdl_Impl
)
, pInfo );
216}
217
218sal_uInt32 SfxViewShell_Impl::m_nLastViewShellId = 0;
219
220SfxViewShell_Impl::SfxViewShell_Impl(SfxViewShellFlags const nFlags)
221: aInterceptorContainer( aMutex )
222, m_bHasPrintOptions(nFlags & SfxViewShellFlags::HAS_PRINTOPTIONS)
223, m_nFamily(0xFFFF) // undefined, default set by TemplateDialog
224, m_pLibreOfficeKitViewCallback(nullptr)
225, m_pLibreOfficeKitViewData(nullptr)
226, m_bTiledSearching(false)
227, m_nViewShellId(SfxViewShell_Impl::m_nLastViewShellId++)
228, m_nDocId(-1)
229{
230}
231
232SfxViewShell_Impl::~SfxViewShell_Impl()
233{
234}
235
236std::vector< SfxInPlaceClient* > *SfxViewShell_Impl::GetIPClients_Impl( bool bCreate ) const
237{
238 if (!mpIPClients && bCreate)
239 mpIPClients.reset(new std::vector< SfxInPlaceClient* >);
240 return mpIPClients.get();
241}
242
243SFX_IMPL_SUPERCLASS_INTERFACE(SfxViewShell,SfxShell)SfxInterface* SfxViewShell::pInterface = nullptr; SfxInterface
* SfxViewShell::GetStaticInterface() { if ( !pInterface ) { pInterface
= new SfxInterface( "SfxViewShell", true, GetInterfaceId(), SfxShell
::GetStaticInterface(), aSfxViewShellSlots_Impl[0], sal_uInt16
(sizeof(aSfxViewShellSlots_Impl) / sizeof(SfxSlot) ) ); InitInterface_Impl
(); } return pInterface; } SfxInterface* SfxViewShell::GetInterface
() const { return GetStaticInterface(); } void SfxViewShell::
RegisterInterface(const SfxModule* pMod) { GetStaticInterface
()->Register(pMod); }
244
245void SfxViewShell::InitInterface_Impl()
246{
247}
248
249
250/** search for a filter name dependent on type and module
251 */
252static OUString impl_retrieveFilterNameFromTypeAndModule(
253 const css::uno::Reference< css::container::XContainerQuery >& rContainerQuery,
254 const OUString& rType,
255 const OUString& rModuleIdentifier,
256 const sal_Int32 nFlags )
257{
258 // Retrieve filter from type
259 css::uno::Sequence< css::beans::NamedValue > aQuery {
260 { "Type", css::uno::makeAny( rType ) },
261 { "DocumentService", css::uno::makeAny( rModuleIdentifier ) }
262 };
263
264 css::uno::Reference< css::container::XEnumeration > xEnumeration =
265 rContainerQuery->createSubSetEnumerationByProperties( aQuery );
266
267 OUString aFoundFilterName;
268 while ( xEnumeration->hasMoreElements() )
269 {
270 ::comphelper::SequenceAsHashMap aFilterPropsHM( xEnumeration->nextElement() );
271 OUString aFilterName = aFilterPropsHM.getUnpackedValueOrDefault(
272 "Name",
273 OUString() );
274
275 sal_Int32 nFilterFlags = aFilterPropsHM.getUnpackedValueOrDefault(
276 "Flags",
277 sal_Int32( 0 ) );
278
279 if ( nFilterFlags & nFlags )
280 {
281 aFoundFilterName = aFilterName;
282 break;
283 }
284 }
285
286 return aFoundFilterName;
287}
288
289namespace {
290
291/** search for an internal typename, which map to the current app module
292 and map also to a "family" of file formats as e.g. PDF/MS Doc/OOo Doc.
293 */
294enum ETypeFamily
295{
296 E_MS_DOC,
297 E_OOO_DOC
298};
299
300}
301
302static OUString impl_searchFormatTypeForApp(const css::uno::Reference< css::frame::XFrame >& xFrame ,
303 ETypeFamily eTypeFamily)
304{
305 try
306 {
307 css::uno::Reference< css::uno::XComponentContext > xContext (::comphelper::getProcessComponentContext());
308 css::uno::Reference< css::frame::XModuleManager2 > xModuleManager(css::frame::ModuleManager::create(xContext));
309
310 OUString sModule = xModuleManager->identify(xFrame);
311 OUString sType ;
312
313 switch(eTypeFamily)
314 {
315 case E_MS_DOC:
316 {
317 if ( sModule == "com.sun.star.text.TextDocument" )
318 sType = "writer_MS_Word_2007";
319 else
320 if ( sModule == "com.sun.star.sheet.SpreadsheetDocument" )
321 sType = "MS Excel 2007 XML";
322 else
323 if ( sModule == "com.sun.star.presentation.PresentationDocument" )
324 sType = "MS PowerPoint 2007 XML";
325 }
326 break;
327
328 case E_OOO_DOC:
329 {
330 if ( sModule == "com.sun.star.text.TextDocument" )
331 sType = "writer8";
332 else
333 if ( sModule == "com.sun.star.sheet.SpreadsheetDocument" )
334 sType = "calc8";
335 else
336 if ( sModule == "com.sun.star.drawing.DrawingDocument" )
337 sType = "draw8";
338 else
339 if ( sModule == "com.sun.star.presentation.PresentationDocument" )
340 sType = "impress8";
341 }
342 break;
343 }
344
345 return sType;
346 }
347 catch (const css::uno::RuntimeException&)
348 {
349 throw;
350 }
351 catch (const css::uno::Exception&)
352 {
353 }
354
355 return OUString();
356}
357
358void SfxViewShell::NewIPClient_Impl( SfxInPlaceClient *pIPClient )
359{
360 pImpl->GetIPClients_Impl()->push_back(pIPClient);
361}
362
363void SfxViewShell::IPClientGone_Impl( SfxInPlaceClient const *pIPClient )
364{
365 std::vector< SfxInPlaceClient* > *pClients = pImpl->GetIPClients_Impl();
366
367 auto it = std::find(pClients->begin(), pClients->end(), pIPClient);
368 if (it != pClients->end())
369 pClients->erase( it );
370}
371
372
373void SfxViewShell::ExecMisc_Impl( SfxRequest &rReq )
374{
375 const sal_uInt16 nId = rReq.GetSlot();
376 switch( nId )
377 {
378 case SID_STYLE_FAMILYTypedWhichId<SfxUInt16Item>(5000 + 553) :
379 {
380 const SfxUInt16Item* pItem = rReq.GetArg<SfxUInt16Item>(nId);
381 if (pItem)
382 {
383 pImpl->m_nFamily = pItem->GetValue();
384 }
385 break;
386 }
387 case SID_ACTIVATE_STYLE_APPLY(5000 + 1715):
388 {
389 uno::Reference< frame::XFrame > xFrame =
390 GetViewFrame()->GetFrame().GetFrameInterface();
391
392 Reference< beans::XPropertySet > xPropSet( xFrame, UNO_QUERY );
393 Reference< frame::XLayoutManager > xLayoutManager;
394 if ( xPropSet.is() )
395 {
396 try
397 {
398 Any aValue = xPropSet->getPropertyValue("LayoutManager");
399 aValue >>= xLayoutManager;
400 if ( xLayoutManager.is() )
401 {
402 uno::Reference< ui::XUIElement > xElement = xLayoutManager->getElement( "private:resource/toolbar/textobjectbar" );
403 if(!xElement.is())
404 {
405 xElement = xLayoutManager->getElement( "private:resource/toolbar/frameobjectbar" );
406 }
407 if(!xElement.is())
408 {
409 xElement = xLayoutManager->getElement( "private:resource/toolbar/oleobjectbar" );
410 }
411 if(xElement.is())
412 {
413 uno::Reference< awt::XWindow > xWin( xElement->getRealInterface(), uno::UNO_QUERY_THROW );
414 VclPtr<vcl::Window> pWin = VCLUnoHelper::GetWindow( xWin );
415 ToolBox* pTextToolbox = dynamic_cast< ToolBox* >( pWin.get() );
416 if( pTextToolbox )
417 {
418 ToolBox::ImplToolItems::size_type nItemCount = pTextToolbox->GetItemCount();
419 for( ToolBox::ImplToolItems::size_type nItem = 0; nItem < nItemCount; ++nItem )
420 {
421 sal_uInt16 nItemId = pTextToolbox->GetItemId( nItem );
422 const OUString& rCommand = pTextToolbox->GetItemCommand( nItemId );
423 if (rCommand == ".uno:StyleApply")
424 {
425 vcl::Window* pItemWin = pTextToolbox->GetItemWindow( nItemId );
426 if( pItemWin )
427 pItemWin->GrabFocus();
428 break;
429 }
430 }
431 }
432 }
433 }
434 }
435 catch (const Exception&)
436 {
437 }
438 }
439 rReq.Done();
440 }
441 break;
442
443 case SID_MAIL_SENDDOCASMS(5000 + 1708):
444 case SID_MAIL_SENDDOCASOOO(5000 + 1709):
445 case SID_MAIL_SENDDOCASPDF(5000 + 1672):
446 case SID_MAIL_SENDDOC(5000 + 331):
447 case SID_MAIL_SENDDOCASFORMAT(5000 + 1707):
448 {
449 SfxObjectShell* pDoc = GetObjectShell();
450 if ( pDoc && pDoc->QueryHiddenInformation(
451 HiddenWarningFact::WhenSaving, GetViewFrame()->GetWindow().GetFrameWeld() ) != RET_YES )
452 break;
453
454
455 SfxMailModel aModel;
456 OUString aDocType;
457
458 const SfxStringItem* pMailRecipient = rReq.GetArg<SfxStringItem>(SID_MAIL_RECIPIENT(5000 + 334));
459 if ( pMailRecipient )
460 {
461 OUString aRecipient( pMailRecipient->GetValue() );
462 OUString aMailToStr("mailto:");
463
464 if ( aRecipient.startsWith( aMailToStr ) )
465 aRecipient = aRecipient.copy( aMailToStr.getLength() );
466 aModel.AddToAddress( aRecipient );
467 }
468 const SfxStringItem* pMailDocType = rReq.GetArg<SfxStringItem>(SID_TYPE_NAME(5000 + 533));
469 if ( pMailDocType )
470 aDocType = pMailDocType->GetValue();
471
472 uno::Reference < frame::XFrame > xFrame( pFrame->GetFrame().GetFrameInterface() );
473 SfxMailModel::SendMailResult eResult = SfxMailModel::SEND_MAIL_ERROR;
474
475 if ( nId == SID_MAIL_SENDDOC(5000 + 331) )
476 eResult = aModel.SaveAndSend( xFrame, OUString() );
477 else if ( nId == SID_MAIL_SENDDOCASPDF(5000 + 1672) )
478 eResult = aModel.SaveAndSend( xFrame, "pdf_Portable_Document_Format");
479 else if ( nId == SID_MAIL_SENDDOCASMS(5000 + 1708) )
480 {
481 aDocType = impl_searchFormatTypeForApp(xFrame, E_MS_DOC);
482 if (!aDocType.isEmpty())
483 eResult = aModel.SaveAndSend( xFrame, aDocType );
484 }
485 else if ( nId == SID_MAIL_SENDDOCASOOO(5000 + 1709) )
486 {
487 aDocType = impl_searchFormatTypeForApp(xFrame, E_OOO_DOC);
488 if (!aDocType.isEmpty())
489 eResult = aModel.SaveAndSend( xFrame, aDocType );
490 }
491
492 if ( eResult == SfxMailModel::SEND_MAIL_ERROR )
493 {
494 vcl::Window* pWin = SfxGetpApp()->GetTopWindow();
495 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(pWin ? pWin->GetFrameWeld() : nullptr,
496 VclMessageType::Info, VclButtonsType::Ok,
497 SfxResId(STR_ERROR_SEND_MAILreinterpret_cast<char const *>("STR_ERROR_SEND_MAIL" "\004"
u8"An error occurred in sending the message. Possible errors could be a missing user account or a defective setup.\nPlease check the %PRODUCTNAME settings or your email program settings."
)
)));
498 xBox->run();
499 rReq.Ignore();
500 }
501 else
502 rReq.Done();
503 }
504 break;
505
506 case SID_BLUETOOTH_SENDDOC(5000 + 1726):
507 {
508 SfxBluetoothModel aModel;
509 SfxObjectShell* pDoc = GetObjectShell();
510 if ( pDoc && pDoc->QueryHiddenInformation(
511 HiddenWarningFact::WhenSaving, GetViewFrame()->GetWindow().GetFrameWeld() ) != RET_YES )
512 break;
513 uno::Reference < frame::XFrame > xFrame( pFrame->GetFrame().GetFrameInterface() );
514 SfxMailModel::SendMailResult eResult = aModel.SaveAndSend( xFrame );
515 if( eResult == SfxMailModel::SEND_MAIL_ERROR )
516 {
517 vcl::Window* pWin = SfxGetpApp()->GetTopWindow();
518 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(pWin ? pWin->GetFrameWeld() : nullptr,
519 VclMessageType::Info, VclButtonsType::Ok,
520 SfxResId(STR_ERROR_SEND_MAILreinterpret_cast<char const *>("STR_ERROR_SEND_MAIL" "\004"
u8"An error occurred in sending the message. Possible errors could be a missing user account or a defective setup.\nPlease check the %PRODUCTNAME settings or your email program settings."
)
)));
521 xBox->run();
522 rReq.Ignore();
523 }
524 else
525 rReq.Done();
526 }
527 break;
528
529 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
530 case SID_WEBHTML(5000 + 393):
531 {
532 css::uno::Reference< lang::XMultiServiceFactory > xSMGR(::comphelper::getProcessServiceFactory(), css::uno::UNO_SET_THROW);
533 css::uno::Reference< uno::XComponentContext > xContext(::comphelper::getProcessComponentContext(), css::uno::UNO_SET_THROW);
534 css::uno::Reference< css::frame::XFrame > xFrame( pFrame->GetFrame().GetFrameInterface() );
535 css::uno::Reference< css::frame::XModel > xModel;
536
537 css::uno::Reference< css::frame::XModuleManager2 > xModuleManager( css::frame::ModuleManager::create(xContext) );
538
539 OUString aModule;
540 try
541 {
542 aModule = xModuleManager->identify( xFrame );
543 }
544 catch (const css::uno::RuntimeException&)
545 {
546 throw;
547 }
548 catch (const css::uno::Exception&)
549 {
550 }
551
552 if ( xFrame.is() )
553 {
554 css::uno::Reference< css::frame::XController > xController = xFrame->getController();
555 if ( xController.is() )
556 xModel = xController->getModel();
557 }
558
559 // We need at least a valid module name and model reference
560 css::uno::Reference< css::frame::XStorable > xStorable( xModel, css::uno::UNO_QUERY );
561 if ( xModel.is() && xStorable.is() )
562 {
563 OUString aFilterName;
564 OUString aTypeName( "generic_HTML" );
565 OUString aFileName;
566
567 OUString aLocation = xStorable->getLocation();
568 INetURLObject aFileObj( aLocation );
569
570 bool bPrivateProtocol = ( aFileObj.GetProtocol() == INetProtocol::PrivSoffice );
571 bool bHasLocation = !aLocation.isEmpty() && !bPrivateProtocol;
572
573 css::uno::Reference< css::container::XContainerQuery > xContainerQuery(
574 xSMGR->createInstance( "com.sun.star.document.FilterFactory" ),
575 css::uno::UNO_QUERY_THROW );
576
577 // Retrieve filter from type
578
579 sal_Int32 nFilterFlags = 0x00000002; // export
580 aFilterName = impl_retrieveFilterNameFromTypeAndModule( xContainerQuery, aTypeName, aModule, nFilterFlags );
581 if ( aFilterName.isEmpty() )
582 {
583 // Draw/Impress uses a different type. 2nd chance try to use alternative type name
584 aFilterName = impl_retrieveFilterNameFromTypeAndModule(
585 xContainerQuery, "graphic_HTML", aModule, nFilterFlags );
586 }
587
588 // No filter found => error
589 // No type and no location => error
590 if ( aFilterName.isEmpty() || aTypeName.isEmpty())
591 {
592 rReq.Done();
593 return;
594 }
595
596 // Use provided save file name. If empty determine file name
597 if ( !bHasLocation )
598 {
599 // Create a default file name with the correct extension
600 aFileName = "webpreview";
601 }
602 else
603 {
604 // Determine file name from model
605 INetURLObject aFObj( xStorable->getLocation() );
606 aFileName = aFObj.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DecodeMechanism::NONE );
607 }
608
609 OSL_ASSERT( !aFilterName.isEmpty() )do { if (true && (!(!aFilterName.isEmpty()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewsh.cxx"
":" "609" ": "), "OSL_ASSERT: %s", "!aFilterName.isEmpty()")
; } } while (false)
;
610 OSL_ASSERT( !aFileName.isEmpty() )do { if (true && (!(!aFileName.isEmpty()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewsh.cxx"
":" "610" ": "), "OSL_ASSERT: %s", "!aFileName.isEmpty()"); }
} while (false)
;
611
612 // Creates a temporary directory to store our predefined file into it (for the
613 // flatpak case, create it in XDG_CACHE_HOME instead of /tmp for technical reasons,
614 // so that it can be accessed by the browser running outside the sandbox):
615 OUString * parent = nullptr;
616 if (flatpak::isFlatpak() && !flatpak::createTemporaryHtmlDirectory(&parent))
617 {
618 SAL_WARN("sfx.view", "cannot create Flatpak html temp dir")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "sfx.view")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "cannot create Flatpak html temp dir"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.view"
), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewsh.cxx"
":" "618" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "cannot create Flatpak html temp dir")
, 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "cannot create Flatpak html temp dir"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.view"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewsh.cxx"
":" "618" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "cannot create Flatpak html temp dir") == 1) { ::
sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.view"), (
"/home/maarten/src/libreoffice/core/sfx2/source/view/viewsh.cxx"
":" "618" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "cannot create Flatpak html temp dir")
, 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "cannot create Flatpak html temp dir"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.view"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewsh.cxx"
":" "618" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
619 }
620 ::utl::TempFile aTempDir( parent, true );
621
622 INetURLObject aFilePathObj( aTempDir.GetURL() );
623 aFilePathObj.insertName( aFileName );
624 aFilePathObj.setExtension( "htm" );
625
626 OUString aFileURL = aFilePathObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
627
628 css::uno::Sequence< css::beans::PropertyValue > aArgs( 1 );
629 aArgs[0].Name = "FilterName";
630 aArgs[0].Value <<= aFilterName;
631
632 // Store document in the html format
633 try
634 {
635 xStorable->storeToURL( aFileURL, aArgs );
636 }
637 catch (const io::IOException&)
638 {
639 rReq.Done();
640 return;
641 }
642
643 sfx2::openUriExternally(aFileURL, true);
644 rReq.Done(true);
645 break;
646 }
647 else
648 {
649 rReq.Done();
650 return;
651 }
652 }
653 }
654}
655
656
657void SfxViewShell::GetState_Impl( SfxItemSet &rSet )
658{
659
660 SfxWhichIter aIter( rSet );
661 SfxObjectShell *pSh = GetViewFrame()->GetObjectShell();
662 for ( sal_uInt16 nSID = aIter.FirstWhich(); nSID; nSID = aIter.NextWhich() )
663 {
664 switch ( nSID )
665 {
666
667 case SID_BLUETOOTH_SENDDOC(5000 + 1726):
668 case SID_MAIL_SENDDOC(5000 + 331):
669 case SID_MAIL_SENDDOCASFORMAT(5000 + 1707):
670 case SID_MAIL_SENDDOCASMS(5000 + 1708):
671 case SID_MAIL_SENDDOCASOOO(5000 + 1709):
672 case SID_MAIL_SENDDOCASPDF(5000 + 1672):
673 {
674#if HAVE_FEATURE_MACOSX_SANDBOX0
675 rSet.DisableItem(nSID);
676#endif
677 if (pSh && pSh->isExportLocked() && nSID != SID_MAIL_SENDDOC(5000 + 331))
678 rSet.DisableItem(nSID);
679 break;
680 }
681 case SID_WEBHTML(5000 + 393):
682 {
683 if (pSh && pSh->isExportLocked())
684 rSet.DisableItem(nSID);
685 break;
686 }
687 // Printer functions
688 case SID_PRINTDOC(5000 + 504):
689 case SID_PRINTDOCDIRECT(5000 + 509):
690 case SID_SETUPPRINTER(5000 + 302):
691 case SID_PRINTER_NAME(5000 + 322):
692 {
693 if (Application::GetSettings().GetMiscSettings().GetDisablePrinting()
694 || (pSh && pSh->isPrintLocked()))
695 {
696 rSet.DisableItem(nSID);
697 break;
698 }
699
700 SfxPrinter *pPrinter = GetPrinter();
701
702 if ( SID_PRINTDOCDIRECT(5000 + 509) == nSID )
703 {
704 OUString aPrinterName;
705 if ( pPrinter != nullptr )
706 aPrinterName = pPrinter->GetName();
707 else
708 aPrinterName = Printer::GetDefaultPrinterName();
709 if ( !aPrinterName.isEmpty() )
710 {
711 uno::Reference < frame::XFrame > xFrame( pFrame->GetFrame().GetFrameInterface() );
712
713 OUStringBuffer aBuffer( 60 );
714 auto aProperties = vcl::CommandInfoProvider::GetCommandProperties(".uno:PrintDefault",
715 vcl::CommandInfoProvider::GetModuleIdentifier(xFrame));
716 aBuffer.append(vcl::CommandInfoProvider::GetLabelForCommand(aProperties));
717 aBuffer.append( " (" );
718 aBuffer.append( aPrinterName );
719 aBuffer.append(')');
720
721 rSet.Put( SfxStringItem( SID_PRINTDOCDIRECT(5000 + 509), aBuffer.makeStringAndClear() ) );
722 }
723 }
724 break;
725 }
726 case SID_STYLE_FAMILYTypedWhichId<SfxUInt16Item>(5000 + 553) :
727 {
728 rSet.Put( SfxUInt16Item( SID_STYLE_FAMILYTypedWhichId<SfxUInt16Item>(5000 + 553), pImpl->m_nFamily ) );
729 break;
730 }
731 }
732 }
733}
734
735
736void SfxViewShell::SetZoomFactor( const Fraction &rZoomX,
737 const Fraction &rZoomY )
738{
739 DBG_ASSERT( GetWindow(), "no window" )do { if (true && (!(GetWindow()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewsh.cxx"
":" "739" ": "), "%s", "no window"); } } while (false)
;
740 MapMode aMap( GetWindow()->GetMapMode() );
741 aMap.SetScaleX( rZoomX );
742 aMap.SetScaleY( rZoomY );
743 GetWindow()->SetMapMode( aMap );
744}
745
746
747ErrCode SfxViewShell::DoVerb(long /*nVerb*/)
748
749/* [Description]
750
751 Virtual Method used to perform a Verb on a selected Object.
752 Since this Object is only known by the derived classes, they must override
753 DoVerb.
754*/
755
756{
757 return ERRCODE_SO_NOVERBSErrCode(ErrCodeArea::So, ErrCodeClass::So, 30);
758}
759
760
761void SfxViewShell::OutplaceActivated( bool bActive )
762{
763 if ( !bActive )
764 GetFrame()->GetFrame().Appear();
765}
766
767
768void SfxViewShell::UIActivating( SfxInPlaceClient* /*pClient*/ )
769{
770 uno::Reference < frame::XFrame > xOwnFrame( pFrame->GetFrame().GetFrameInterface() );
771 uno::Reference < frame::XFramesSupplier > xParentFrame = xOwnFrame->getCreator();
772 if ( xParentFrame.is() )
773 xParentFrame->setActiveFrame( xOwnFrame );
774
775 pFrame->GetBindings().HidePopups();
776 pFrame->GetDispatcher()->Update_Impl( true );
777}
778
779
780void SfxViewShell::UIDeactivated( SfxInPlaceClient* /*pClient*/ )
781{
782 if ( !pFrame->GetFrame().IsClosing_Impl() || SfxViewFrame::Current() != pFrame )
783 pFrame->GetDispatcher()->Update_Impl( true );
784 pFrame->GetBindings().HidePopups(false);
785
786 pFrame->GetBindings().InvalidateAll(true);
787}
788
789
790SfxInPlaceClient* SfxViewShell::FindIPClient
791(
792 const uno::Reference < embed::XEmbeddedObject >& xObj,
793 vcl::Window* pObjParentWin
794) const
795{
796 std::vector< SfxInPlaceClient* > *pClients = pImpl->GetIPClients_Impl(false);
797 if ( !pClients )
798 return nullptr;
799
800 if( !pObjParentWin )
801 pObjParentWin = GetWindow();
802 for (SfxInPlaceClient* pIPClient : *pClients)
803 {
804 if ( pIPClient->GetObject() == xObj && pIPClient->GetEditWin() == pObjParentWin )
805 return pIPClient;
806 }
807
808 return nullptr;
809}
810
811
812SfxInPlaceClient* SfxViewShell::GetIPClient() const
813{
814 return GetUIActiveClient();
815}
816
817
818SfxInPlaceClient* SfxViewShell::GetUIActiveIPClient_Impl() const
819{
820 // this method is needed as long as SFX still manages the border space for ChildWindows (see SfxFrame::Resize)
821 std::vector< SfxInPlaceClient* > *pClients = pImpl->GetIPClients_Impl(false);
822 if ( !pClients )
823 return nullptr;
824
825 for (SfxInPlaceClient* pIPClient : *pClients)
826 {
827 if ( pIPClient->IsUIActive() )
828 return pIPClient;
829 }
830
831 return nullptr;
832}
833
834SfxInPlaceClient* SfxViewShell::GetUIActiveClient() const
835{
836 std::vector< SfxInPlaceClient* > *pClients = pImpl->GetIPClients_Impl(false);
837 if ( !pClients )
838 return nullptr;
839
840 const bool bIsTiledRendering = comphelper::LibreOfficeKit::isActive();
841
842 for (SfxInPlaceClient* pIPClient : *pClients)
843 {
844 if ( pIPClient->IsObjectUIActive() || ( bIsTiledRendering && pIPClient->IsObjectInPlaceActive() ) )
845 return pIPClient;
846 }
847
848 return nullptr;
849}
850
851
852void SfxViewShell::Activate( bool bMDI )
853{
854 if ( bMDI )
855 {
856 SfxObjectShell *pSh = GetViewFrame()->GetObjectShell();
857 if ( pSh->GetModel().is() )
858 pSh->GetModel()->setCurrentController( GetViewFrame()->GetFrame().GetController() );
859
860 SetCurrentDocument();
861 }
862}
863
864
865void SfxViewShell::Deactivate(bool /*bMDI*/)
866{
867}
868
869
870void SfxViewShell::Move()
871
872/* [Description]
873
874 This virtual Method is called when the window displayed in the
875 SfxViewShell gets a StarView-Move() notification.
876
877 This base implementation does not have to be called. .
878
879 [Note]
880
881 This Method can be used to cancel a selection, in order to catch the
882 mouse movement which is due to moving a window.
883
884 For now the notification does not work In-Place.
885*/
886
887{
888}
889
890
891void SfxViewShell::OuterResizePixel
892(
893 const Point& /*rToolOffset*/,// Upper left corner Tools in Frame-Window
894 const Size& /*rSize*/ // All available sizes.
895)
896
897/* [Description]
898
899 Override this Method to be able to react to the size-change of
900 the View. Thus the View is defined as the Edit window and also the
901 attached Tools are defined (for example the ruler).
902
903 The Edit window must not be changed either in size or position.
904
905 The Vis-Area of SfxObjectShell, its scale and position can be changed
906 here. The main use is to change the size of the Vis-Area.
907
908 If the Border is changed due to the new calculation then this has to be set
909 by <SfxViewShell::SetBorderPixel(const SvBorder&)>. The Positioning of Tools
910 is only allowed after the calling of 'SetBorderPixel'.
911
912 [Example]
913
914 void AppViewSh::OuterViewResizePixel( const Point &rOfs, const Size &rSz )
915 {
916 // Calculate Tool position and size externally, do not set!
917 // (due to the following Border calculation)
918 Point aHLinPos...; Size aHLinSz...;
919 ...
920
921 // Calculate and Set a Border of Tools which matches rSize.
922 SvBorder aBorder...
923 SetBorderPixel( aBorder ); // Allow Positioning from here on.
924
925 // Arrange Tools
926 pHLin->SetPosSizePixel( aHLinPos, aHLinSz );
927 ...
928 }
929
930 [Cross-reference]
931
932 <SfxViewShell::InnerResizePixel(const Point&,const Size& rSize)>
933*/
934
935{
936 SetBorderPixel( SvBorder() );
937}
938
939
940void SfxViewShell::InnerResizePixel
941(
942 const Point& /*rToolOffset*/,// Upper left corner Tools in Frame-Window
943 const Size& /*rSize*/, // All available sizes.
944 bool
945)
946
947/* [Description]
948
949 Override this Method to be able to react to the size-change of
950 the Edit window.
951
952 The Edit window must not be changed either in size or position.
953 Neither the Vis-Area of SfxObjectShell nor its scale or position are
954 allowed to be changed
955
956 If the Border is changed due to the new calculation then is has to be set
957 by <SfxViewShell::SetBorderPixel(const SvBorder&)>.
958 The Positioning of Tools is only allowed after the calling of
959 'SetBorderPixel'.
960
961
962 [Note]
963
964 void AppViewSh::InnerViewResizePixel( const Point &rOfs, const Size &rSz )
965 {
966 // Calculate Tool position and size internally, do not set!
967 // (due to the following Border calculation)
968 Point aHLinPos...; Size aHLinSz...;
969 ...
970
971 // Calculate and Set a Border of Tools which matches rSize.
972 SvBorder aBorder...
973 SetBorderPixel( aBorder ); // Allow Positioning from here on.
974
975 // Arrange Tools
976 pHLin->SetPosSizePixel( aHLinPos, aHLinSz );
977 ...
978 }
979
980 [Cross-reference]
981
982 <SfxViewShell::OuterResizePixel(const Point&,const Size& rSize)>
983*/
984
985{
986 SetBorderPixel( SvBorder() );
987}
988
989
990void SfxViewShell::InvalidateBorder()
991{
992 DBG_ASSERT( GetViewFrame(), "SfxViewShell without SfxViewFrame" )do { if (true && (!(GetViewFrame()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewsh.cxx"
":" "992" ": "), "%s", "SfxViewShell without SfxViewFrame");
} } while (false)
;
993
994 GetViewFrame()->InvalidateBorderImpl( this );
995 if (pImpl->m_pController.is())
996 {
997 pImpl->m_pController->BorderWidthsChanged_Impl();
998 }
999}
1000
1001
1002void SfxViewShell::SetBorderPixel( const SvBorder &rBorder )
1003{
1004 DBG_ASSERT( GetViewFrame(), "SfxViewShell without SfxViewFrame" )do { if (true && (!(GetViewFrame()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewsh.cxx"
":" "1004" ": "), "%s", "SfxViewShell without SfxViewFrame")
; } } while (false)
;
1005
1006 GetViewFrame()->SetBorderPixelImpl( this, rBorder );
1007
1008 // notify related controller that border size is changed
1009 if (pImpl->m_pController.is())
1010 {
1011 pImpl->m_pController->BorderWidthsChanged_Impl();
1012 }
1013}
1014
1015
1016const SvBorder& SfxViewShell::GetBorderPixel() const
1017{
1018 DBG_ASSERT( GetViewFrame(), "SfxViewShell without SfxViewFrame" )do { if (true && (!(GetViewFrame()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewsh.cxx"
":" "1018" ": "), "%s", "SfxViewShell without SfxViewFrame")
; } } while (false)
;
1019
1020 return GetViewFrame()->GetBorderPixelImpl();
1021}
1022
1023
1024void SfxViewShell::SetWindow
1025(
1026 vcl::Window* pViewPort // For example Null pointer in the Destructor.
1027)
1028
1029/* [Description]
1030
1031 With this method the SfxViewShell is set in the data window. This is
1032 needed for the in-place container and for restoring the proper focus.
1033
1034 Even in-place-active the conversion of the ViewPort Windows is forbidden.
1035*/
1036
1037{
1038 if( pWindow == pViewPort )
1039 return;
1040
1041 // Disconnect existing IP-Clients if possible
1042 DisconnectAllClients();
1043
1044 // Switch View-Port
1045 bool bHadFocus = pWindow && pWindow->HasChildPathFocus( true );
1046 pWindow = pViewPort;
1047
1048 if( pWindow )
1049 {
1050 // Disable automatic GUI mirroring (right-to-left) for document windows
1051 pWindow->EnableRTL( false );
1052 }
1053
1054 if ( bHadFocus && pWindow )
1055 pWindow->GrabFocus();
1056 //TODO/CLEANUP
1057 //Do we still need this Method?!
1058 //SfxGetpApp()->GrabFocus( pWindow );
1059}
1060
1061
1062SfxViewShell::SfxViewShell
1063(
1064 SfxViewFrame* pViewFrame, /* <SfxViewFrame>, which will be
1065 displayed in this View */
1066 SfxViewShellFlags nFlags /* See <SfxViewShell-Flags> */
1067)
1068
1069: SfxShell(this)
1070, pImpl( new SfxViewShell_Impl(nFlags) )
1071, pFrame(pViewFrame)
1072, pWindow(nullptr)
1073, bNoNewWindow( nFlags & SfxViewShellFlags::NO_NEWWINDOW )
1074, mbPrinterSettingsModified(false)
1075, maLOKLanguageTag(LANGUAGE_NONELanguageType(0x00FF))
1076, maLOKLocale(LANGUAGE_NONELanguageType(0x00FF))
1077, maLOKDeviceFormFactor(LOKDeviceFormFactor::UNKNOWN)
1078{
1079 SetMargin( pViewFrame->GetMargin_Impl() );
1080
1081 SetPool( &pViewFrame->GetObjectShell()->GetPool() );
1082 StartListening(*pViewFrame->GetObjectShell());
1083
1084 // Insert into list
1085 SfxViewShellArr_Impl &rViewArr = SfxGetpApp()->GetViewShells_Impl();
1086 rViewArr.push_back(this);
1087
1088 if (comphelper::LibreOfficeKit::isActive())
1089 {
1090 maLOKLanguageTag = SfxLokHelper::getDefaultLanguage();
1091 maLOKLocale = SfxLokHelper::getDefaultLanguage();
1092
1093 maLOKDeviceFormFactor = SfxLokHelper::getDeviceFormFactor();
1094
1095 vcl::Window* pFrameWin = pViewFrame->GetWindow().GetFrameWindow();
1096 if (pFrameWin && !pFrameWin->GetLOKNotifier())
1097 pFrameWin->SetLOKNotifier(this, true);
1098 }
1099}
1100
1101
1102SfxViewShell::~SfxViewShell()
1103{
1104 // Remove from list
1105 const SfxViewShell *pThis = this;
1106 SfxViewShellArr_Impl &rViewArr = SfxGetpApp()->GetViewShells_Impl();
1107 SfxViewShellArr_Impl::iterator it = std::find( rViewArr.begin(), rViewArr.end(), pThis );
1108 rViewArr.erase( it );
1109
1110 if ( pImpl->xClipboardListener.is() )
1111 {
1112 pImpl->xClipboardListener->DisconnectViewShell();
1113 pImpl->xClipboardListener = nullptr;
1114 }
1115
1116 if (pImpl->m_pController.is())
1117 {
1118 pImpl->m_pController->ReleaseShell_Impl();
1119 pImpl->m_pController.clear();
1120 }
1121
1122 vcl::Window* pFrameWin = GetViewFrame()->GetWindow().GetFrameWindow();
1123 if (pFrameWin && pFrameWin->GetLOKNotifier() == this)
1124 pFrameWin->ReleaseLOKNotifier();
1125}
1126
1127bool SfxViewShell::PrepareClose
1128(
1129 bool bUI // TRUE: Allow Dialog and so on, FALSE: silent-mode
1130)
1131{
1132 if (GetViewFrame()->GetWindow().GetLOKNotifier() == this)
1133 GetViewFrame()->GetWindow().ReleaseLOKNotifier();
1134
1135 SfxPrinter *pPrinter = GetPrinter();
1136 if ( pPrinter && pPrinter->IsPrinting() )
1137 {
1138 if ( bUI )
1139 {
1140 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetViewFrame()->GetWindow().GetFrameWeld(),
1141 VclMessageType::Info, VclButtonsType::Ok,
1142 SfxResId(STR_CANT_CLOSEreinterpret_cast<char const *>("STR_CANT_CLOSE" "\004" u8"The document cannot be closed because a\n print job is being carried out."
)
)));
1143 xBox->run();
1144 }
1145
1146 return false;
1147 }
1148
1149 if( GetViewFrame()->IsInModalMode() )
1150 return false;
1151
1152 if( bUI && GetViewFrame()->GetDispatcher()->IsLocked() )
1153 return false;
1154
1155 return true;
1156}
1157
1158
1159SfxViewShell* SfxViewShell::Current()
1160{
1161 SfxViewFrame *pCurrent = SfxViewFrame::Current();
1162 return pCurrent ? pCurrent->GetViewShell() : nullptr;
1163}
1164
1165
1166SfxViewShell* SfxViewShell::Get( const Reference< XController>& i_rController )
1167{
1168 if ( !i_rController.is() )
1169 return nullptr;
1170
1171 for ( SfxViewShell* pViewShell = SfxViewShell::GetFirst( false );
1172 pViewShell;
1173 pViewShell = SfxViewShell::GetNext( *pViewShell, false )
1174 )
1175 {
1176 if ( pViewShell->GetController() == i_rController )
1177 return pViewShell;
1178 }
1179 return nullptr;
1180}
1181
1182
1183SdrView* SfxViewShell::GetDrawView() const
1184
1185/* [Description]
1186
1187 This virtual Method has to be overloaded by the sub classes, to be able
1188 make the Property-Editor available.
1189
1190 The default implementation does always return zero.
1191*/
1192
1193{
1194 return nullptr;
1195}
1196
1197
1198OUString SfxViewShell::GetSelectionText
1199(
1200 bool /*bCompleteWords*/ /* FALSE (default)
1201 Only the actual selected text is returned.
1202
1203 TRUE
1204 The selected text is expanded so that only
1205 whole words are returned. As word separators
1206 these are used: white spaces and punctuation
1207 ".,;" and single and double quotes.
1208 */
1209)
1210
1211/* [Description]
1212
1213 Override this Method to return a text that
1214 is included in the current selection. This is for example used when
1215 sending emails.
1216
1217 When called with "CompleteWords == TRUE", it is for example sufficient
1218 with having the Cursor positioned somewhere within a URL in-order
1219 to have the entire URL returned.
1220*/
1221
1222{
1223 return OUString();
1224}
1225
1226
1227bool SfxViewShell::HasSelection( bool ) const
1228
1229/* [Description]
1230
1231 With this virtual Method can a for example a Dialog be queried, to
1232 check if something is selected in the current view. If the Parameter
1233 is <BOOL> TRUE then it is checked whether some text is selected.
1234*/
1235
1236{
1237 return false;
1238}
1239
1240void SfxViewShell::AddSubShell( SfxShell& rShell )
1241{
1242 pImpl->aArr.push_back(&rShell);
1243 SfxDispatcher *pDisp = pFrame->GetDispatcher();
1244 if ( pDisp->IsActive(*this) )
1245 {
1246 pDisp->Push(rShell);
1247 pDisp->Flush();
1248 }
1249}
1250
1251void SfxViewShell::RemoveSubShell( SfxShell* pShell )
1252{
1253 SfxDispatcher *pDisp = pFrame->GetDispatcher();
1254 if ( !pShell )
1255 {
1256 size_t nCount = pImpl->aArr.size();
1257 if ( pDisp->IsActive(*this) )
1258 {
1259 for(size_t n = nCount; n > 0; --n)
1260 pDisp->Pop(*pImpl->aArr[n - 1]);
1261 pDisp->Flush();
1262 }
1263 pImpl->aArr.clear();
1264 }
1265 else
1266 {
1267 SfxShellArr_Impl::iterator i = std::find(pImpl->aArr.begin(), pImpl->aArr.end(), pShell);
1268 if(i != pImpl->aArr.end())
1269 {
1270 pImpl->aArr.erase(i);
1271 if(pDisp->IsActive(*this))
1272 {
1273 pDisp->RemoveShell_Impl(*pShell);
1274 pDisp->Flush();
1275 }
1276 }
1277 }
1278}
1279
1280SfxShell* SfxViewShell::GetSubShell( sal_uInt16 nNo )
1281{
1282 sal_uInt16 nCount = pImpl->aArr.size();
1283 if(nNo < nCount)
1284 return pImpl->aArr[nCount - nNo - 1];
1285 return nullptr;
1286}
1287
1288void SfxViewShell::PushSubShells_Impl( bool bPush )
1289{
1290 SfxDispatcher *pDisp = pFrame->GetDispatcher();
1291 if ( bPush )
1292 {
1293 for (auto const& elem : pImpl->aArr)
1294 pDisp->Push(*elem);
1295 }
1296 else if(!pImpl->aArr.empty())
1297 {
1298 SfxShell& rPopUntil = *pImpl->aArr[0];
1299 if ( pDisp->GetShellLevel( rPopUntil ) != USHRT_MAX(32767 *2 +1) )
1300 pDisp->Pop( rPopUntil, SfxDispatcherPopFlags::POP_UNTIL );
1301 }
1302
1303 pDisp->Flush();
1304}
1305
1306
1307void SfxViewShell::WriteUserData( OUString&, bool )
1308{
1309}
1310
1311
1312void SfxViewShell::ReadUserData(const OUString&, bool )
1313{
1314}
1315
1316void SfxViewShell::ReadUserDataSequence ( const uno::Sequence < beans::PropertyValue >& )
1317{
1318}
1319
1320void SfxViewShell::WriteUserDataSequence ( uno::Sequence < beans::PropertyValue >& )
1321{
1322}
1323
1324
1325// returns the first shell of spec. type viewing the specified doc.
1326SfxViewShell* SfxViewShell::GetFirst
1327(
1328 bool bOnlyVisible,
1329 const std::function< bool ( const SfxViewShell* ) >& isViewShell
1330)
1331{
1332 // search for a SfxViewShell of the specified type
1333 SfxViewShellArr_Impl &rShells = SfxGetpApp()->GetViewShells_Impl();
1334 SfxViewFrameArr_Impl &rFrames = SfxGetpApp()->GetViewFrames_Impl();
1335 for (SfxViewShell* pShell : rShells)
1336 {
1337 if ( pShell )
1338 {
1339 // sometimes dangling SfxViewShells exist that point to a dead SfxViewFrame
1340 // these ViewShells shouldn't be accessible anymore
1341 // a destroyed ViewFrame is not in the ViewFrame array anymore, so checking this array helps
1342 for (SfxViewFrame* pFrame : rFrames)
1343 {
1344 if ( pFrame == pShell->GetViewFrame() )
1345 {
1346 // only ViewShells with a valid ViewFrame will be returned
1347 if ( ( !bOnlyVisible || pFrame->IsVisible() ) && (!isViewShell || isViewShell(pShell)))
1348 return pShell;
1349 break;
1350 }
1351 }
1352 }
1353 }
1354
1355 return nullptr;
1356}
1357
1358
1359// returns the next shell of spec. type viewing the specified doc.
1360
1361SfxViewShell* SfxViewShell::GetNext
1362(
1363 const SfxViewShell& rPrev,
1364 bool bOnlyVisible,
1365 const std::function<bool ( const SfxViewShell* )>& isViewShell
1366)
1367{
1368 SfxViewShellArr_Impl &rShells = SfxGetpApp()->GetViewShells_Impl();
1369 SfxViewFrameArr_Impl &rFrames = SfxGetpApp()->GetViewFrames_Impl();
1370 size_t nPos;
1371 for ( nPos = 0; nPos < rShells.size(); ++nPos )
1372 if ( rShells[nPos] == &rPrev )
1373 break;
1374
1375 for ( ++nPos; nPos < rShells.size(); ++nPos )
1376 {
1377 SfxViewShell *pShell = rShells[nPos];
1378 if ( pShell )
1379 {
1380 // sometimes dangling SfxViewShells exist that point to a dead SfxViewFrame
1381 // these ViewShells shouldn't be accessible anymore
1382 // a destroyed ViewFrame is not in the ViewFrame array anymore, so checking this array helps
1383 for (SfxViewFrame* pFrame : rFrames)
1384 {
1385 if ( pFrame == pShell->GetViewFrame() )
1386 {
1387 // only ViewShells with a valid ViewFrame will be returned
1388 if ( ( !bOnlyVisible || pFrame->IsVisible() ) && (!isViewShell || isViewShell(pShell)) )
1389 return pShell;
1390 break;
1391 }
1392 }
1393 }
1394 }
1395
1396 return nullptr;
1397}
1398
1399
1400void SfxViewShell::Notify( SfxBroadcaster& rBC,
1401 const SfxHint& rHint )
1402{
1403 const SfxEventHint* pEventHint = dynamic_cast<const SfxEventHint*>(&rHint);
1404 if ( !(pEventHint && pEventHint->GetEventId() == SfxEventHintId::LoadFinished) )
1405 return;
1406
1407 if ( !GetController().is() )
1408 return;
1409
1410 // avoid access to dangling ViewShells
1411 SfxViewFrameArr_Impl &rFrames = SfxGetpApp()->GetViewFrames_Impl();
1412 for (SfxViewFrame* frame : rFrames)
1413 {
1414 if ( frame == GetViewFrame() && &rBC == GetObjectShell() )
1415 {
1416 SfxItemSet* pSet = GetObjectShell()->GetMedium()->GetItemSet();
1417 const SfxUnoAnyItem* pItem = SfxItemSet::GetItem<SfxUnoAnyItem>(pSet, SID_VIEW_DATA(5000 + 1582), false);
1418 if ( pItem )
1419 {
1420 pImpl->m_pController->restoreViewData( pItem->GetValue() );
1421 pSet->ClearItem( SID_VIEW_DATA(5000 + 1582) );
1422 }
1423 break;
1424 }
1425 }
1426}
1427
1428bool SfxViewShell::ExecKey_Impl(const KeyEvent& aKey)
1429{
1430 if (!pImpl->m_xAccExec)
1431 {
1432 pImpl->m_xAccExec = ::svt::AcceleratorExecute::createAcceleratorHelper();
1433 pImpl->m_xAccExec->init(::comphelper::getProcessComponentContext(),
1434 pFrame->GetFrame().GetFrameInterface());
1435 }
1436
1437 return pImpl->m_xAccExec->execute(aKey.GetKeyCode());
1438}
1439
1440void SfxViewShell::registerLibreOfficeKitViewCallback(LibreOfficeKitCallback pCallback, void* pData)
1441{
1442 pImpl->m_pLibreOfficeKitViewCallback = pCallback;
1443 pImpl->m_pLibreOfficeKitViewData = pData;
1444
1445 afterCallbackRegistered();
1446
1447 if (!pCallback)
1448 return;
1449
1450 // Ask other views to tell us about their cursors.
1451 SfxViewShell* pViewShell = SfxViewShell::GetFirst();
1452 while (pViewShell)
1453 {
1454 if (pViewShell->GetDocId() == GetDocId())
1455 pViewShell->NotifyCursor(this);
1456 pViewShell = SfxViewShell::GetNext(*pViewShell);
1457 }
1458}
1459
1460void SfxViewShell::libreOfficeKitViewCallback(int nType, const char* pPayload) const
1461{
1462 if (!comphelper::LibreOfficeKit::isActive())
1463 return;
1464
1465 if (comphelper::LibreOfficeKit::isTiledPainting() && nType != LOK_CALLBACK_FORM_FIELD_BUTTON)
1466 return;
1467
1468 if (pImpl->m_bTiledSearching)
1469 {
1470 switch (nType)
1471 {
1472 case LOK_CALLBACK_TEXT_SELECTION:
1473 case LOK_CALLBACK_TEXT_VIEW_SELECTION:
1474 case LOK_CALLBACK_TEXT_SELECTION_START:
1475 case LOK_CALLBACK_TEXT_SELECTION_END:
1476 case LOK_CALLBACK_GRAPHIC_SELECTION:
1477 case LOK_CALLBACK_GRAPHIC_VIEW_SELECTION:
1478 return;
1479 }
1480 }
1481
1482 if (pImpl->m_pLibreOfficeKitViewCallback)
1483 pImpl->m_pLibreOfficeKitViewCallback(nType, pPayload, pImpl->m_pLibreOfficeKitViewData);
1484 else
1485 SAL_INFO(do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "sfx.view")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "SfxViewShell::libreOfficeKitViewCallback no callback set! Dropped payload of type "
<< lokCallbackTypeToString(nType) << ": [" <<
pPayload << ']') == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx.view"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewsh.cxx"
":" "1488" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "SfxViewShell::libreOfficeKitViewCallback no callback set! Dropped payload of type "
<< lokCallbackTypeToString(nType) << ": [" <<
pPayload << ']'), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "SfxViewShell::libreOfficeKitViewCallback no callback set! Dropped payload of type "
<< lokCallbackTypeToString(nType) << ": [" <<
pPayload << ']'; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx.view"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewsh.cxx"
":" "1488" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "SfxViewShell::libreOfficeKitViewCallback no callback set! Dropped payload of type "
<< lokCallbackTypeToString(nType) << ": [" <<
pPayload << ']') == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx.view"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewsh.cxx"
":" "1488" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "SfxViewShell::libreOfficeKitViewCallback no callback set! Dropped payload of type "
<< lokCallbackTypeToString(nType) << ": [" <<
pPayload << ']'), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "SfxViewShell::libreOfficeKitViewCallback no callback set! Dropped payload of type "
<< lokCallbackTypeToString(nType) << ": [" <<
pPayload << ']'; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx.view"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewsh.cxx"
":" "1488" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
1486 "sfx.view",do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "sfx.view")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "SfxViewShell::libreOfficeKitViewCallback no callback set! Dropped payload of type "
<< lokCallbackTypeToString(nType) << ": [" <<
pPayload << ']') == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx.view"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewsh.cxx"
":" "1488" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "SfxViewShell::libreOfficeKitViewCallback no callback set! Dropped payload of type "
<< lokCallbackTypeToString(nType) << ": [" <<
pPayload << ']'), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "SfxViewShell::libreOfficeKitViewCallback no callback set! Dropped payload of type "
<< lokCallbackTypeToString(nType) << ": [" <<
pPayload << ']'; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx.view"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewsh.cxx"
":" "1488" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "SfxViewShell::libreOfficeKitViewCallback no callback set! Dropped payload of type "
<< lokCallbackTypeToString(nType) << ": [" <<
pPayload << ']') == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx.view"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewsh.cxx"
":" "1488" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "SfxViewShell::libreOfficeKitViewCallback no callback set! Dropped payload of type "
<< lokCallbackTypeToString(nType) << ": [" <<
pPayload << ']'), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "SfxViewShell::libreOfficeKitViewCallback no callback set! Dropped payload of type "
<< lokCallbackTypeToString(nType) << ": [" <<
pPayload << ']'; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx.view"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewsh.cxx"
":" "1488" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
1487 "SfxViewShell::libreOfficeKitViewCallback no callback set! Dropped payload of type "do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "sfx.view")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "SfxViewShell::libreOfficeKitViewCallback no callback set! Dropped payload of type "
<< lokCallbackTypeToString(nType) << ": [" <<
pPayload << ']') == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx.view"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewsh.cxx"
":" "1488" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "SfxViewShell::libreOfficeKitViewCallback no callback set! Dropped payload of type "
<< lokCallbackTypeToString(nType) << ": [" <<
pPayload << ']'), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "SfxViewShell::libreOfficeKitViewCallback no callback set! Dropped payload of type "
<< lokCallbackTypeToString(nType) << ": [" <<
pPayload << ']'; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx.view"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewsh.cxx"
":" "1488" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "SfxViewShell::libreOfficeKitViewCallback no callback set! Dropped payload of type "
<< lokCallbackTypeToString(nType) << ": [" <<
pPayload << ']') == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx.view"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewsh.cxx"
":" "1488" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "SfxViewShell::libreOfficeKitViewCallback no callback set! Dropped payload of type "
<< lokCallbackTypeToString(nType) << ": [" <<
pPayload << ']'), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "SfxViewShell::libreOfficeKitViewCallback no callback set! Dropped payload of type "
<< lokCallbackTypeToString(nType) << ": [" <<
pPayload << ']'; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx.view"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewsh.cxx"
":" "1488" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
1488 << lokCallbackTypeToString(nType) << ": [" << pPayload << ']')do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "sfx.view")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "SfxViewShell::libreOfficeKitViewCallback no callback set! Dropped payload of type "
<< lokCallbackTypeToString(nType) << ": [" <<
pPayload << ']') == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx.view"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewsh.cxx"
":" "1488" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "SfxViewShell::libreOfficeKitViewCallback no callback set! Dropped payload of type "
<< lokCallbackTypeToString(nType) << ": [" <<
pPayload << ']'), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "SfxViewShell::libreOfficeKitViewCallback no callback set! Dropped payload of type "
<< lokCallbackTypeToString(nType) << ": [" <<
pPayload << ']'; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx.view"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewsh.cxx"
":" "1488" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "SfxViewShell::libreOfficeKitViewCallback no callback set! Dropped payload of type "
<< lokCallbackTypeToString(nType) << ": [" <<
pPayload << ']') == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx.view"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewsh.cxx"
":" "1488" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "SfxViewShell::libreOfficeKitViewCallback no callback set! Dropped payload of type "
<< lokCallbackTypeToString(nType) << ": [" <<
pPayload << ']'), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "SfxViewShell::libreOfficeKitViewCallback no callback set! Dropped payload of type "
<< lokCallbackTypeToString(nType) << ": [" <<
pPayload << ']'; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("sfx.view"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewsh.cxx"
":" "1488" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1489}
1490
1491void SfxViewShell::afterCallbackRegistered()
1492{
1493}
1494
1495vcl::Window* SfxViewShell::GetEditWindowForActiveOLEObj() const
1496{
1497 vcl::Window* pEditWin = nullptr;
1498 SfxInPlaceClient* pIPClient = GetIPClient();
1499 if (pIPClient)
1500 {
1501 pEditWin = pIPClient->GetEditWin();
1502 }
1503 return pEditWin;
1504}
1505
1506void SfxViewShell::SetLOKLanguageTag(const OUString& rBcp47LanguageTag)
1507{
1508 LanguageTag aTag(rBcp47LanguageTag, true);
1509
1510 css::uno::Sequence<OUString> inst(officecfg::Setup::Office::InstalledLocales::get()->getElementNames());
1511 LanguageTag aFallbackTag = LanguageTag(getInstalledLocaleForSystemUILanguage(inst, /* bRequestInstallIfMissing */ false, rBcp47LanguageTag), true).makeFallback();
1512
1513 // If we want de-CH, and the de localisation is available, we don't want to use de-DE as then
1514 // the magic in Translate::get() won't turn ess-zet into double s. Possibly other similar cases?
1515 if (comphelper::LibreOfficeKit::isActive() && aTag.getLanguage() == aFallbackTag.getLanguage())
1516 maLOKLanguageTag = aTag;
1517 else
1518 maLOKLanguageTag = aFallbackTag;
1519}
1520
1521void SfxViewShell::SetLOKLocale(const OUString& rBcp47LanguageTag)
1522{
1523 maLOKLocale = LanguageTag(rBcp47LanguageTag, true).makeFallback();
1524}
1525
1526void SfxViewShell::NotifyCursor(SfxViewShell* /*pViewShell*/) const
1527{
1528}
1529
1530void SfxViewShell::setTiledSearching(bool bTiledSearching)
1531{
1532 pImpl->m_bTiledSearching = bTiledSearching;
1533}
1534
1535int SfxViewShell::getPart() const
1536{
1537 return 0;
1538}
1539
1540ViewShellId SfxViewShell::GetViewShellId() const
1541{
1542 return pImpl->m_nViewShellId;
1543}
1544
1545void SfxViewShell::SetDocId(ViewShellDocId nId)
1546{
1547 assert(static_cast<int>(pImpl->m_nDocId) == -1)(static_cast <bool> (static_cast<int>(pImpl->m_nDocId
) == -1) ? void (0) : __assert_fail ("static_cast<int>(pImpl->m_nDocId) == -1"
, "/home/maarten/src/libreoffice/core/sfx2/source/view/viewsh.cxx"
, 1547, __extension__ __PRETTY_FUNCTION__))
;
1548 pImpl->m_nDocId = nId;
1549}
1550
1551ViewShellDocId SfxViewShell::GetDocId() const
1552{
1553 return pImpl->m_nDocId;
1554}
1555
1556void SfxViewShell::NotifyOtherViews(int nType, const OString& rKey, const OString& rPayload)
1557{
1558 SfxLokHelper::notifyOtherViews(this, nType, rKey, rPayload);
1559}
1560
1561void SfxViewShell::NotifyOtherView(OutlinerViewShell* pOther, int nType, const OString& rKey, const OString& rPayload)
1562{
1563 auto pOtherShell = dynamic_cast<SfxViewShell*>(pOther);
1564 if (!pOtherShell)
1565 return;
1566
1567 SfxLokHelper::notifyOtherView(this, pOtherShell, nType, rKey, rPayload);
1568}
1569
1570void SfxViewShell::dumpAsXml(xmlTextWriterPtr pWriter) const
1571{
1572 xmlTextWriterStartElement(pWriter, BAD_CAST(xmlChar *)("SfxViewShell"));
1573 xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST(xmlChar *)("ptr"), "%p", this);
1574 xmlTextWriterWriteAttribute(pWriter, BAD_CAST(xmlChar *)("id"), BAD_CAST(xmlChar *)(OString::number(static_cast<sal_Int32>(GetViewShellId())).getStr()));
1575 xmlTextWriterEndElement(pWriter);
1576}
1577
1578bool SfxViewShell::KeyInput( const KeyEvent &rKeyEvent )
1579
1580/* [Description]
1581
1582 This Method executes the KeyEvent 'rKeyEvent' of the Keys (Accelerator)
1583 configured either direct or indirect (for example by the Application)
1584 in the SfxViewShell.
1585
1586 [Return value]
1587
1588 bool TRUE
1589 The Key (Accelerator) is configured and the
1590 associated Handler was called
1591
1592 FALSE
1593 The Key (Accelerator) is not configured and
1594 subsequently no Handler was called
1595
1596 [Cross-reference]
1597
1598 <SfxApplication::KeyInput(const KeyEvent&)>
1599*/
1600{
1601 return ExecKey_Impl(rKeyEvent);
1602}
1603
1604bool SfxViewShell::GlobalKeyInput_Impl( const KeyEvent &rKeyEvent )
1605{
1606 return ExecKey_Impl(rKeyEvent);
1607}
1608
1609
1610void SfxViewShell::ShowCursor( bool /*bOn*/ )
1611
1612/* [Description]
1613
1614 Subclasses must override this Method so that SFx can switch the
1615 Cursor on and off, for example while a <SfxProgress> is running.
1616*/
1617
1618{
1619}
1620
1621
1622void SfxViewShell::ResetAllClients_Impl( SfxInPlaceClient const *pIP )
1623{
1624
1625 std::vector< SfxInPlaceClient* > *pClients = pImpl->GetIPClients_Impl(false);
1626 if ( !pClients )
1627 return;
1628
1629 for (SfxInPlaceClient* pIPClient : *pClients)
1630 {
1631 if( pIPClient != pIP )
1632 pIPClient->ResetObject();
1633 }
1634}
1635
1636
1637void SfxViewShell::DisconnectAllClients()
1638{
1639 std::vector< SfxInPlaceClient* > *pClients = pImpl->GetIPClients_Impl(false);
1640 if ( !pClients )
1641 return;
1642
1643 for ( size_t n = 0; n < pClients->size(); )
1644 // clients will remove themselves from the list
1645 delete pClients->at( n );
1646}
1647
1648
1649void SfxViewShell::QueryObjAreaPixel( tools::Rectangle& ) const
1650{
1651}
1652
1653
1654void SfxViewShell::VisAreaChanged()
1655{
1656 std::vector< SfxInPlaceClient* > *pClients = pImpl->GetIPClients_Impl(false);
1657 if ( !pClients )
1658 return;
1659
1660 for (SfxInPlaceClient* pIPClient : *pClients)
1661 {
1662 if ( pIPClient->IsObjectInPlaceActive() )
1663 // client is active, notify client that the VisArea might have changed
1664 pIPClient->VisAreaChanged();
1665 }
1666}
1667
1668
1669void SfxViewShell::CheckIPClient_Impl(
1670 SfxInPlaceClient const *const pIPClient, const tools::Rectangle& rVisArea)
1671{
1672 if ( GetObjectShell()->IsInClose() )
1673 return;
1674
1675 bool bAlwaysActive =
1676 ( ( pIPClient->GetObjectMiscStatus() & embed::EmbedMisc::EMBED_ACTIVATEIMMEDIATELY ) != 0 );
1677 bool bActiveWhenVisible =
1678 ( pIPClient->GetObjectMiscStatus() & embed::EmbedMisc::MS_EMBED_ACTIVATEWHENVISIBLE ) != 0;
1679
1680 // this method is called when a client is created
1681 if (pIPClient->IsObjectInPlaceActive())
1682 return;
1683
1684 // object in client is currently not active
1685 // check if the object wants to be activated always or when it becomes at least partially visible
1686 // TODO/LATER: maybe we should use the scaled area instead of the ObjArea?!
1687 if (bAlwaysActive || (bActiveWhenVisible && rVisArea.IsOver(pIPClient->GetObjArea())))
1688 {
1689 try
1690 {
1691 pIPClient->GetObject()->changeState( embed::EmbedStates::INPLACE_ACTIVE );
1692 }
1693 catch (const uno::Exception&)
1694 {
1695 TOOLS_WARN_EXCEPTION("sfx.view", "SfxViewShell::CheckIPClient_Impl")do { css::uno::Any tools_warn_exception( DbgGetCaughtException
() ); do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "sfx.view")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "SfxViewShell::CheckIPClient_Impl"
<< " " << exceptionToString(tools_warn_exception
)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), (
"sfx.view"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewsh.cxx"
":" "1695" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "SfxViewShell::CheckIPClient_Impl" <<
" " << exceptionToString(tools_warn_exception)), 0); }
else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "SfxViewShell::CheckIPClient_Impl" << " " <<
exceptionToString(tools_warn_exception); ::sal::detail::log(
(::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.view"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewsh.cxx"
":" "1695" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "SfxViewShell::CheckIPClient_Impl" << " " <<
exceptionToString(tools_warn_exception)) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.view"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewsh.cxx"
":" "1695" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "SfxViewShell::CheckIPClient_Impl" <<
" " << exceptionToString(tools_warn_exception)), 0); }
else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "SfxViewShell::CheckIPClient_Impl" << " " <<
exceptionToString(tools_warn_exception); ::sal::detail::log(
(::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.view"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewsh.cxx"
":" "1695" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false); } while (false)
;
1696 }
1697 }
1698}
1699
1700
1701SfxObjectShell* SfxViewShell::GetObjectShell()
1702{
1703 return pFrame ? pFrame->GetObjectShell() : nullptr;
1704}
1705
1706
1707Reference< XModel > SfxViewShell::GetCurrentDocument() const
1708{
1709 Reference< XModel > xDocument;
1710
1711 const SfxObjectShell* pDocShell( const_cast< SfxViewShell* >( this )->GetObjectShell() );
1712 OSL_ENSURE( pDocShell, "SfxViewFrame::GetCurrentDocument: no DocShell!?" )do { if (true && (!(pDocShell))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewsh.cxx"
":" "1712" ": "), "%s", "SfxViewFrame::GetCurrentDocument: no DocShell!?"
); } } while (false)
;
1713 if ( pDocShell )
1714 xDocument = pDocShell->GetModel();
1715 return xDocument;
1716}
1717
1718
1719void SfxViewShell::SetCurrentDocument() const
1720{
1721 uno::Reference< frame::XModel > xDocument( GetCurrentDocument() );
1722 if ( xDocument.is() )
1723 SfxObjectShell::SetCurrentComponent( xDocument );
1724}
1725
1726
1727const Size& SfxViewShell::GetMargin() const
1728{
1729 return pImpl->aMargin;
1730}
1731
1732
1733void SfxViewShell::SetMargin( const Size& rSize )
1734{
1735 // the default margin was verified using www.apple.com !!
1736 Size aMargin = rSize;
1737 if ( aMargin.Width() == -1 )
1738 aMargin.setWidth( DEFAULT_MARGIN_WIDTH8 );
1739 if ( aMargin.Height() == -1 )
1740 aMargin.setHeight( DEFAULT_MARGIN_HEIGHT12 );
1741
1742 if ( aMargin != pImpl->aMargin )
1743 {
1744 pImpl->aMargin = aMargin;
1745 MarginChanged();
1746 }
1747}
1748
1749void SfxViewShell::MarginChanged()
1750{
1751}
1752
1753void SfxViewShell::JumpToMark( const OUString& rMark )
1754{
1755 SfxStringItem aMarkItem( SID_JUMPTOMARK(5000 + 598), rMark );
1756 GetViewFrame()->GetDispatcher()->ExecuteList(
1757 SID_JUMPTOMARK(5000 + 598),
1758 SfxCallMode::SYNCHRON|SfxCallMode::RECORD,
1759 { &aMarkItem });
1760}
1761
1762void SfxViewShell::SetController( SfxBaseController* pController )
1763{
1764 pImpl->m_pController = pController;
1765
1766 // there should be no old listener, but if there is one, it should be disconnected
1767 if ( pImpl->xClipboardListener.is() )
1768 pImpl->xClipboardListener->DisconnectViewShell();
1769
1770 pImpl->xClipboardListener = new SfxClipboardChangeListener( this, GetClipboardNotifier() );
1771}
1772
1773Reference < XController > SfxViewShell::GetController() const
1774{
1775 return pImpl->m_pController.get();
1776}
1777
1778SfxBaseController* SfxViewShell::GetBaseController_Impl() const
1779{
1780 return pImpl->m_pController.get();
1781}
1782
1783void SfxViewShell::AddContextMenuInterceptor_Impl( const uno::Reference< ui::XContextMenuInterceptor >& xInterceptor )
1784{
1785 pImpl->aInterceptorContainer.addInterface( xInterceptor );
1786}
1787
1788void SfxViewShell::RemoveContextMenuInterceptor_Impl( const uno::Reference< ui::XContextMenuInterceptor >& xInterceptor )
1789{
1790 pImpl->aInterceptorContainer.removeInterface( xInterceptor );
1791}
1792
1793static void Change( Menu* pMenu, SfxViewShell* pView )
1794{
1795 SfxDispatcher *pDisp = pView->GetViewFrame()->GetDispatcher();
1796 sal_uInt16 nCount = pMenu->GetItemCount();
1797 for ( sal_uInt16 nPos=0; nPos<nCount; ++nPos )
1798 {
1799 sal_uInt16 nId = pMenu->GetItemId(nPos);
1800 OUString aCmd = pMenu->GetItemCommand(nId);
1801 PopupMenu* pPopup = pMenu->GetPopupMenu(nId);
1802 if ( pPopup )
1803 {
1804 Change( pPopup, pView );
1805 }
1806 else if ( nId < 5000 )
1807 {
1808 if ( aCmd.startsWith(".uno:") )
1809 {
1810 for (sal_uInt16 nIdx=0;;)
1811 {
1812 SfxShell *pShell=pDisp->GetShell(nIdx++);
1813 if (pShell == nullptr)
1814 break;
1815 const SfxInterface *pIFace = pShell->GetInterface();
1816 const SfxSlot* pSlot = pIFace->GetSlot( aCmd );
1817 if ( pSlot )
1818 {
1819 pMenu->InsertItem( pSlot->GetSlotId(), pMenu->GetItemText( nId ),
1820 pMenu->GetItemBits( nId ), OString(), nPos );
1821 pMenu->SetItemCommand( pSlot->GetSlotId(), aCmd );
1822 pMenu->RemoveItem( nPos+1 );
1823 break;
1824 }
1825 }
1826 }
1827 }
1828 }
1829}
1830
1831
1832bool SfxViewShell::TryContextMenuInterception( Menu& rIn, const OUString& rMenuIdentifier, VclPtr<Menu>& rpOut, ui::ContextMenuExecuteEvent aEvent )
1833{
1834 rpOut = nullptr;
1835 bool bModified = false;
1836
1837 // create container from menu
1838 aEvent.ActionTriggerContainer = ::framework::ActionTriggerHelper::CreateActionTriggerContainerFromMenu(
1839 &rIn, &rMenuIdentifier );
1840
1841 // get selection from controller
1842 aEvent.Selection.set( GetController(), uno::UNO_QUERY );
1843
1844 // call interceptors
1845 ::comphelper::OInterfaceIteratorHelper2 aIt( pImpl->aInterceptorContainer );
1846 while( aIt.hasMoreElements() )
1
Loop condition is true. Entering loop body
1847 {
1848 try
1849 {
1850 ui::ContextMenuInterceptorAction eAction;
1851 {
1852 SolarMutexReleaser rel;
1853 eAction = static_cast<ui::XContextMenuInterceptor*>(aIt.next())->notifyContextMenuExecute( aEvent );
1854 }
1855 switch ( eAction )
2
Control jumps to 'case 2:' at line 1860
1856 {
1857 case ui::ContextMenuInterceptorAction_CANCELLED :
1858 // interceptor does not want execution
1859 return false;
1860 case ui::ContextMenuInterceptorAction_EXECUTE_MODIFIED :
1861 // interceptor wants his modified menu to be executed
1862 bModified = true;
1863 break;
3
Execution continues on line 1881
1864 case ui::ContextMenuInterceptorAction_CONTINUE_MODIFIED :
1865 // interceptor has modified menu, but allows for calling other interceptors
1866 bModified = true;
1867 continue;
1868 case ui::ContextMenuInterceptorAction_IGNORED :
1869 // interceptor is indifferent
1870 continue;
1871 default:
1872 OSL_FAIL("Wrong return value of ContextMenuInterceptor!")do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewsh.cxx"
":" "1872" ": "), "%s", "Wrong return value of ContextMenuInterceptor!"
); } } while (false)
;
1873 continue;
1874 }
1875 }
1876 catch (...)
1877 {
1878 aIt.remove();
1879 }
1880
1881 break;
4
Execution continues on line 1884
1882 }
1883
1884 if ( bModified
4.1
'bModified' is true
4.1
'bModified' is true
4.1
'bModified' is true
4.1
'bModified' is true
)
5
Taking true branch
1885 {
1886 // container was modified, create a new window out of it
1887 rpOut = VclPtr<PopupMenu>::Create();
6
Calling 'VclPtr::Create'
8
Returned allocated memory
9
Calling implicit destructor for 'VclPtr<PopupMenu>'
10
Calling '~Reference'
17
Returning from '~Reference'
18
Returning from destructor for 'VclPtr<PopupMenu>'
1888 ::framework::ActionTriggerHelper::CreateMenuFromActionTriggerContainer( rpOut, aEvent.ActionTriggerContainer );
19
Calling 'VclPtr::operator Menu *'
1889
1890 Change( rpOut, this );
1891 }
1892
1893 return true;
1894}
1895
1896bool SfxViewShell::TryContextMenuInterception( Menu& rMenu, const OUString& rMenuIdentifier, css::ui::ContextMenuExecuteEvent aEvent )
1897{
1898 bool bModified = false;
1899
1900 // create container from menu
1901 aEvent.ActionTriggerContainer = ::framework::ActionTriggerHelper::CreateActionTriggerContainerFromMenu( &rMenu, &rMenuIdentifier );
1902
1903 // get selection from controller
1904 aEvent.Selection = css::uno::Reference< css::view::XSelectionSupplier >( GetController(), css::uno::UNO_QUERY );
1905
1906 // call interceptors
1907 ::comphelper::OInterfaceIteratorHelper2 aIt( pImpl->aInterceptorContainer );
1908 while( aIt.hasMoreElements() )
1909 {
1910 try
1911 {
1912 css::ui::ContextMenuInterceptorAction eAction;
1913 {
1914 SolarMutexReleaser rel;
1915 eAction = static_cast< css::ui::XContextMenuInterceptor* >( aIt.next() )->notifyContextMenuExecute( aEvent );
1916 }
1917 switch ( eAction )
1918 {
1919 case css::ui::ContextMenuInterceptorAction_CANCELLED:
1920 // interceptor does not want execution
1921 return false;
1922 case css::ui::ContextMenuInterceptorAction_EXECUTE_MODIFIED:
1923 // interceptor wants his modified menu to be executed
1924 bModified = true;
1925 break;
1926 case css::ui::ContextMenuInterceptorAction_CONTINUE_MODIFIED:
1927 // interceptor has modified menu, but allows for calling other interceptors
1928 bModified = true;
1929 continue;
1930 case css::ui::ContextMenuInterceptorAction_IGNORED:
1931 // interceptor is indifferent
1932 continue;
1933 default:
1934 SAL_WARN( "sfx.view", "Wrong return value of ContextMenuInterceptor!" )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "sfx.view")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "Wrong return value of ContextMenuInterceptor!"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.view"
), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewsh.cxx"
":" "1934" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Wrong return value of ContextMenuInterceptor!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Wrong return value of ContextMenuInterceptor!"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.view")
, ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewsh.cxx"
":" "1934" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Wrong return value of ContextMenuInterceptor!") ==
1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.view"
), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewsh.cxx"
":" "1934" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Wrong return value of ContextMenuInterceptor!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Wrong return value of ContextMenuInterceptor!"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.view")
, ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewsh.cxx"
":" "1934" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1935 continue;
1936 }
1937 }
1938 catch (...)
1939 {
1940 aIt.remove();
1941 }
1942
1943 break;
1944 }
1945
1946 if ( bModified )
1947 {
1948 rMenu.Clear();
1949 ::framework::ActionTriggerHelper::CreateMenuFromActionTriggerContainer( &rMenu, aEvent.ActionTriggerContainer );
1950 }
1951
1952 return true;
1953}
1954
1955bool SfxViewShell::HandleNotifyEvent_Impl( NotifyEvent const & rEvent )
1956{
1957 if (pImpl->m_pController.is())
1958 return pImpl->m_pController->HandleEvent_Impl( rEvent );
1959 return false;
1960}
1961
1962bool SfxViewShell::HasKeyListeners_Impl() const
1963{
1964 return (pImpl->m_pController.is())
1965 && pImpl->m_pController->HasKeyListeners_Impl();
1966}
1967
1968bool SfxViewShell::HasMouseClickListeners_Impl() const
1969{
1970 return (pImpl->m_pController.is())
1971 && pImpl->m_pController->HasMouseClickListeners_Impl();
1972}
1973
1974bool SfxViewShell::Escape()
1975{
1976 return GetViewFrame()->GetBindings().Execute( SID_TERMINATE_INPLACEACTIVATION(5000 + 1702) );
1977}
1978
1979Reference< view::XRenderable > SfxViewShell::GetRenderable()
1980{
1981 Reference< view::XRenderable >xRender;
1982 SfxObjectShell* pObj = GetObjectShell();
1983 if( pObj )
1984 {
1985 Reference< frame::XModel > xModel( pObj->GetModel() );
1986 if( xModel.is() )
1987 xRender.set( xModel, UNO_QUERY );
1988 }
1989 return xRender;
1990}
1991
1992void SfxViewShell::notifyWindow(vcl::LOKWindowId nDialogId, const OUString& rAction, const std::vector<vcl::LOKPayloadItem>& rPayload) const
1993{
1994 SfxLokHelper::notifyWindow(this, nDialogId, rAction, rPayload);
1995}
1996
1997uno::Reference< datatransfer::clipboard::XClipboardNotifier > SfxViewShell::GetClipboardNotifier() const
1998{
1999 uno::Reference< datatransfer::clipboard::XClipboardNotifier > xClipboardNotifier;
2000 if ( GetViewFrame() )
2001 xClipboardNotifier.set( GetViewFrame()->GetWindow().GetClipboard(), uno::UNO_QUERY );
2002
2003 return xClipboardNotifier;
2004}
2005
2006void SfxViewShell::AddRemoveClipboardListener( const uno::Reference < datatransfer::clipboard::XClipboardListener >& rClp, bool bAdd )
2007{
2008 try
2009 {
2010 if ( GetViewFrame() )
2011 {
2012 uno::Reference< datatransfer::clipboard::XClipboard > xClipboard( GetViewFrame()->GetWindow().GetClipboard() );
2013 if( xClipboard.is() )
2014 {
2015 uno::Reference< datatransfer::clipboard::XClipboardNotifier > xClpbrdNtfr( xClipboard, uno::UNO_QUERY );
2016 if( xClpbrdNtfr.is() )
2017 {
2018 if( bAdd )
2019 xClpbrdNtfr->addClipboardListener( rClp );
2020 else
2021 xClpbrdNtfr->removeClipboardListener( rClp );
2022 }
2023 }
2024 }
2025 }
2026 catch (const uno::Exception&)
2027 {
2028 }
2029}
2030
2031weld::Window* SfxViewShell::GetFrameWeld() const
2032{
2033 return pWindow ? pWindow->GetFrameWeld() : nullptr;
2034}
2035
2036/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx

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
36class VclReferenceBase;
37
38namespace vcl::detail {
39
40template<typename>
41constexpr bool isIncompleteOrDerivedFromVclReferenceBase(...) { return true; }
42
43template<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 */
56template <class reference_type>
57class 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
66public:
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 );
7
Memory is allocated
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();
20
Calling 'Reference::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
218template<typename T1, typename T2>
219inline bool operator ==(VclPtr<T1> const & p1, VclPtr<T2> const & p2) {
220 return p1.get() == p2.get();
221}
222
223template<typename T> inline bool operator ==(VclPtr<T> const & p1, T const * p2)
224{
225 return p1.get() == p2;
226}
227
228template<typename T> inline bool operator ==(VclPtr<T> const & p1, T * p2) {
229 return p1.get() == p2;
230}
231
232template<typename T> inline bool operator ==(T const * p1, VclPtr<T> const & p2)
233{
234 return p1 == p2.get();
235}
236
237template<typename T> inline bool operator ==(T * p1, VclPtr<T> const & p2) {
238 return p1 == p2.get();
239}
240
241template<typename T1, typename T2>
242inline bool operator !=(VclPtr<T1> const & p1, VclPtr<T2> const & p2) {
243 return !(p1 == p2);
244}
245
246template<typename T> inline bool operator !=(VclPtr<T> const & p1, T const * p2)
247{
248 return !(p1 == p2);
249}
250
251template<typename T> inline bool operator !=(VclPtr<T> const & p1, T * p2) {
252 return !(p1 == p2);
253}
254
255template<typename T> inline bool operator !=(T const * p1, VclPtr<T> const & p2)
256{
257 return !(p1 == p2);
258}
259
260template<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 */
274template <class reference_type>
275class SAL_WARN_UNUSED__attribute__((warn_unused)) VclPtrInstance final : public VclPtr<reference_type>
276{
277public:
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
290template <class reference_type>
291class ScopedVclPtr : public VclPtr<reference_type>
292{
293public:
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
378private:
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
387protected:
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
406template <class reference_type>
407class SAL_WARN_UNUSED__attribute__((warn_unused)) ScopedVclPtrInstance final : public ScopedVclPtr<reference_type>
408{
409public:
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
421private:
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: */

/home/maarten/src/libreoffice/core/include/rtl/ref.hxx

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
34namespace rtl
35{
36
37/** Template reference class for reference type.
38*/
39template <class reference_type>
40class Reference
41{
42 /** The <b>reference_type</b> body pointer.
43 */
44 reference_type * m_pBody;
45
46
47public:
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
10.1
Field 'm_pBody' is non-null
10.1
Field 'm_pBody' is non-null
10.1
Field 'm_pBody' is non-null
10.1
Field 'm_pBody' is non-null
)
11
Taking true branch
113 m_pBody->release();
12
Calling 'VclReferenceBase::release'
16
Returning; memory was released
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;
21
Use of memory after it is freed
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
277namespace 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*/
286template<typename T>
287struct 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: */

/home/maarten/src/libreoffice/core/include/vcl/vclreferencebase.hxx

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
25class VCL_DLLPUBLIC__attribute__ ((visibility("default"))) VclReferenceBase
26{
27 mutable oslInterlockedCount mnRefCnt;
28
29 template<typename T> friend class VclPtr;
30
31public:
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)
13
Assuming the condition is true
14
Taking true branch
40 delete this;
15
Memory is released
41 }
42#ifdef DBG_UTIL
43#ifndef _WIN32
44 sal_Int32 getRefCount() const { return mnRefCnt; }
45#endif
46#endif
47
48
49private:
50 VclReferenceBase(const VclReferenceBase&) = delete;
51 VclReferenceBase& operator=(const VclReferenceBase&) = delete;
52
53 bool mbDisposed : 1;
54
55protected:
56 VclReferenceBase();
57protected:
58 virtual ~VclReferenceBase();
59
60protected:
61 virtual void dispose();
62
63public:
64 void disposeOnce();
65 bool isDisposed() const { return mbDisposed; }
66
67};
68#endif