1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <config_features.h>
22 #include <boost/property_tree/json_parser.hpp>
24 #include <sal/log.hxx>
25 #include <svl/stritem.hxx>
26 #include <svl/eitem.hxx>
27 #include <svl/whiter.hxx>
29 #include <vcl/svapp.hxx>
30 #include <vcl/toolbox.hxx>
31 #include <vcl/weld.hxx>
32 #include <svl/intitem.hxx>
33 #include <svtools/langhelp.hxx>
34 #include <com/sun/star/awt/XPopupMenu.hpp>
35 #include <com/sun/star/frame/XLayoutManager.hpp>
36 #include <com/sun/star/frame/ModuleManager.hpp>
37 #include <com/sun/star/io/IOException.hpp>
38 #include <com/sun/star/beans/XPropertySet.hpp>
39 #include <com/sun/star/embed/EmbedStates.hpp>
40 #include <com/sun/star/embed/EmbedMisc.hpp>
41 #include <com/sun/star/embed/XEmbeddedObject.hpp>
42 #include <com/sun/star/container/XContainerQuery.hpp>
43 #include <com/sun/star/frame/XStorable.hpp>
44 #include <com/sun/star/frame/XModel.hpp>
45 #include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
46 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
47 #include <com/sun/star/datatransfer/clipboard/XClipboardListener.hpp>
48 #include <com/sun/star/datatransfer/clipboard/XClipboardNotifier.hpp>
49 #include <com/sun/star/view/XRenderable.hpp>
50 #include <com/sun/star/uno/Reference.hxx>
51 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
52 #include <com/sun/star/accessibility/XAccessibleContext.hpp>
53 #include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
54 #include <com/sun/star/accessibility/XAccessibleSelection.hpp>
55 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
56 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
57 #include <com/sun/star/accessibility/XAccessibleText.hpp>
58 #include <cppuhelper/implbase.hxx>
59 #include <com/sun/star/ui/XAcceleratorConfiguration.hpp>
61 #include <cppuhelper/weakref.hxx>
63 #include <com/sun/star/accessibility/XAccessibleTextAttributes.hpp>
64 #include <com/sun/star/accessibility/AccessibleTextType.hpp>
65 #include <com/sun/star/awt/FontSlant.hpp>
67 #include <comphelper/diagnose_ex.hxx>
68 #include <tools/urlobj.hxx>
69 #include <unotools/tempfile.hxx>
70 #include <svtools/soerr.hxx>
71 #include <tools/svborder.hxx>
73 #include <framework/actiontriggerhelper.hxx>
74 #include <comphelper/lok.hxx>
75 #include <comphelper/processfactory.hxx>
76 #include <comphelper/propertyvalue.hxx>
77 #include <comphelper/sequenceashashmap.hxx>
78 #include <toolkit/helper/vclunohelper.hxx>
79 #include <vcl/settings.hxx>
80 #include <vcl/commandinfoprovider.hxx>
81 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
83 #include <officecfg/Setup.hxx>
84 #include <sfx2/app.hxx>
85 #include <sfx2/flatpak.hxx>
86 #include <sfx2/viewsh.hxx>
87 #include "viewimp.hxx"
88 #include <sfx2/sfxresid.hxx>
89 #include <sfx2/request.hxx>
90 #include <sfx2/printer.hxx>
91 #include <sfx2/docfile.hxx>
92 #include <sfx2/dispatch.hxx>
93 #include <sfx2/strings.hrc>
94 #include <sfx2/sfxbasecontroller.hxx>
95 #include <sfx2/mailmodelapi.hxx>
96 #include <bluthsndapi.hxx>
97 #include <sfx2/viewfrm.hxx>
98 #include <sfx2/event.hxx>
99 #include <sfx2/ipclient.hxx>
100 #include <sfx2/sfxsids.hrc>
101 #include <sfx2/objface.hxx>
102 #include <sfx2/lokhelper.hxx>
103 #include <sfx2/lokcallback.hxx>
104 #include <openuriexternally.hxx>
107 #include <libxml/xmlwriter.h>
108 #include <toolkit/awt/vclxmenu.hxx>
109 #include <unordered_map>
111 using namespace ::com::sun::star
;
112 using namespace ::com::sun::star::uno
;
113 using namespace ::com::sun::star::frame
;
114 using namespace ::com::sun::star::beans
;
115 using namespace ::com::sun::star::util
;
116 using namespace ::cppu
;
118 #define ShellClass_SfxViewShell
119 #include <sfxslots.hxx>
122 class SfxClipboardChangeListener
: public ::cppu::WeakImplHelper
<
123 datatransfer::clipboard::XClipboardListener
>
126 SfxClipboardChangeListener( SfxViewShell
* pView
, uno::Reference
< datatransfer::clipboard::XClipboardNotifier
> xClpbrdNtfr
);
129 virtual void SAL_CALL
disposing( const lang::EventObject
& rEventObject
) override
;
131 // XClipboardListener
132 virtual void SAL_CALL
changedContents( const datatransfer::clipboard::ClipboardEvent
& rEventObject
) override
;
134 void DisconnectViewShell() { m_pViewShell
= nullptr; }
135 void ChangedContents();
139 ASYNCEXECUTE_CMD_DISPOSING
,
140 ASYNCEXECUTE_CMD_CHANGEDCONTENTS
143 struct AsyncExecuteInfo
145 AsyncExecuteInfo( AsyncExecuteCmd eCmd
, SfxClipboardChangeListener
* pListener
) :
146 m_eCmd( eCmd
), m_xListener( pListener
) {}
148 AsyncExecuteCmd m_eCmd
;
149 rtl::Reference
<SfxClipboardChangeListener
> m_xListener
;
153 SfxViewShell
* m_pViewShell
;
154 uno::Reference
< datatransfer::clipboard::XClipboardNotifier
> m_xClpbrdNtfr
;
155 uno::Reference
< lang::XComponent
> m_xCtrl
;
157 DECL_STATIC_LINK( SfxClipboardChangeListener
, AsyncExecuteHdl_Impl
, void*, void );
160 SfxClipboardChangeListener::SfxClipboardChangeListener( SfxViewShell
* pView
, uno::Reference
< datatransfer::clipboard::XClipboardNotifier
> xClpbrdNtfr
)
161 : m_pViewShell( nullptr ), m_xClpbrdNtfr(std::move( xClpbrdNtfr
)), m_xCtrl(pView
->GetController())
165 m_xCtrl
->addEventListener( uno::Reference
< lang::XEventListener
> ( static_cast < lang::XEventListener
* >( this ) ) );
166 m_pViewShell
= pView
;
168 if ( m_xClpbrdNtfr
.is() )
170 m_xClpbrdNtfr
->addClipboardListener( uno::Reference
< datatransfer::clipboard::XClipboardListener
>(
171 static_cast< datatransfer::clipboard::XClipboardListener
* >( this )));
175 void SfxClipboardChangeListener::ChangedContents()
177 const SolarMutexGuard aGuard
;
181 SfxBindings
& rBind
= m_pViewShell
->GetViewFrame().GetBindings();
182 rBind
.Invalidate(SID_PASTE
);
183 rBind
.Invalidate(SID_PASTE_SPECIAL
);
184 rBind
.Invalidate(SID_CLIPBOARD_FORMAT_ITEMS
);
186 if (comphelper::LibreOfficeKit::isActive())
188 // In the future we might send the payload as well.
189 SfxLokHelper::notifyAllViews(LOK_CALLBACK_CLIPBOARD_CHANGED
, "");
193 IMPL_STATIC_LINK( SfxClipboardChangeListener
, AsyncExecuteHdl_Impl
, void*, p
, void )
195 AsyncExecuteInfo
* pAsyncExecuteInfo
= static_cast<AsyncExecuteInfo
*>(p
);
196 if ( pAsyncExecuteInfo
)
198 if ( pAsyncExecuteInfo
->m_xListener
.is() )
200 if ( pAsyncExecuteInfo
->m_eCmd
== ASYNCEXECUTE_CMD_DISPOSING
)
201 pAsyncExecuteInfo
->m_xListener
->DisconnectViewShell();
202 else if ( pAsyncExecuteInfo
->m_eCmd
== ASYNCEXECUTE_CMD_CHANGEDCONTENTS
)
203 pAsyncExecuteInfo
->m_xListener
->ChangedContents();
206 delete pAsyncExecuteInfo
;
209 void SAL_CALL
SfxClipboardChangeListener::disposing( const lang::EventObject
& /*rEventObject*/ )
211 // Either clipboard or ViewShell is going to be destroyed -> no interest in listening anymore
212 uno::Reference
< lang::XComponent
> xCtrl( m_xCtrl
);
213 uno::Reference
< datatransfer::clipboard::XClipboardNotifier
> xNotify( m_xClpbrdNtfr
);
215 uno::Reference
< datatransfer::clipboard::XClipboardListener
> xThis( static_cast< datatransfer::clipboard::XClipboardListener
* >( this ));
217 xCtrl
->removeEventListener( uno::Reference
< lang::XEventListener
> ( static_cast < lang::XEventListener
* >( this )));
219 xNotify
->removeClipboardListener( xThis
);
221 // Make asynchronous call to avoid locking SolarMutex which is the
222 // root for many deadlocks, especially in conjunction with the "Windows"
223 // based single thread apartment clipboard code!
224 AsyncExecuteInfo
* pInfo
= new AsyncExecuteInfo( ASYNCEXECUTE_CMD_DISPOSING
, this );
225 if (!Application::PostUserEvent( LINK( nullptr, SfxClipboardChangeListener
, AsyncExecuteHdl_Impl
), pInfo
))
229 void SAL_CALL
SfxClipboardChangeListener::changedContents( const datatransfer::clipboard::ClipboardEvent
& )
231 // Make asynchronous call to avoid locking SolarMutex which is the
232 // root for many deadlocks, especially in conjunction with the "Windows"
233 // based single thread apartment clipboard code!
234 AsyncExecuteInfo
* pInfo
= new AsyncExecuteInfo( ASYNCEXECUTE_CMD_CHANGEDCONTENTS
, this );
235 if (!Application::PostUserEvent( LINK( nullptr, SfxClipboardChangeListener
, AsyncExecuteHdl_Impl
), pInfo
))
239 class LOKDocumentFocusListener
:
240 public ::cppu::WeakImplHelper
< accessibility::XAccessibleEventListener
>
242 static constexpr sal_Int64 MAX_ATTACHABLE_CHILDREN
= 30;
244 const SfxViewShell
* m_pViewShell
;
245 std::set
< uno::Reference
< uno::XInterface
> > m_aRefList
;
246 OUString m_sFocusedParagraph
;
247 bool m_bFocusedParagraphNotified
;
248 sal_Int32 m_nCaretPosition
;
249 sal_Int32 m_nSelectionStart
;
250 sal_Int32 m_nSelectionEnd
;
251 OUString m_sSelectedText
;
252 bool m_bIsEditingCell
;
253 OUString m_sSelectedCellAddress
;
256 LOKDocumentFocusListener(const SfxViewShell
* pViewShell
);
258 /// @throws lang::IndexOutOfBoundsException
259 /// @throws uno::RuntimeException
260 void attachRecursive(
261 const uno::Reference
< accessibility::XAccessible
>& xAccessible
264 /// @throws lang::IndexOutOfBoundsException
265 /// @throws uno::RuntimeException
266 void attachRecursive(
267 const uno::Reference
< accessibility::XAccessible
>& xAccessible
,
268 const uno::Reference
< accessibility::XAccessibleContext
>& xContext
271 /// @throws lang::IndexOutOfBoundsException
272 /// @throws uno::RuntimeException
273 void attachRecursive(
274 const uno::Reference
< accessibility::XAccessible
>& xAccessible
,
275 const uno::Reference
< accessibility::XAccessibleContext
>& xContext
,
276 const sal_Int64 nStateSet
279 /// @throws lang::IndexOutOfBoundsException
280 /// @throws uno::RuntimeException
281 void detachRecursive(
282 const uno::Reference
< accessibility::XAccessible
>& xAccessible
285 /// @throws lang::IndexOutOfBoundsException
286 /// @throws uno::RuntimeException
287 void detachRecursive(
288 const uno::Reference
< accessibility::XAccessibleContext
>& xContext
291 /// @throws lang::IndexOutOfBoundsException
292 /// @throws uno::RuntimeException
293 void detachRecursive(
294 const uno::Reference
< accessibility::XAccessibleContext
>& xContext
,
295 const sal_Int64 nStateSet
298 /// @throws lang::IndexOutOfBoundsException
299 /// @throws uno::RuntimeException
300 static uno::Reference
< accessibility::XAccessible
> getAccessible(const lang::EventObject
& aEvent
);
303 virtual void SAL_CALL
disposing( const lang::EventObject
& Source
) override
;
305 // XAccessibleEventListener
306 virtual void SAL_CALL
notifyEvent( const accessibility::AccessibleEventObject
& aEvent
) override
;
308 void notifyFocusedParagraphChanged();
309 void notifyCaretChanged();
310 void notifyTextSelectionChanged();
312 OUString
getFocusedParagraph() const;
313 int getCaretPosition() const;
316 LOKDocumentFocusListener::LOKDocumentFocusListener(const SfxViewShell
* pViewShell
)
317 : m_pViewShell(pViewShell
)
318 , m_bFocusedParagraphNotified(false)
319 , m_nCaretPosition(0)
320 , m_nSelectionStart(0)
322 , m_bIsEditingCell(false)
326 OUString
LOKDocumentFocusListener::getFocusedParagraph() const
328 SAL_INFO("lok.a11y", "LOKDocumentFocusListener::getFocusedParagraph: " << m_sFocusedParagraph
);
329 const_cast<LOKDocumentFocusListener
*>(this)->m_bFocusedParagraphNotified
= true;
331 sal_Int32 nSelectionStart
= m_nSelectionStart
;
332 sal_Int32 nSelectionEnd
= m_nSelectionEnd
;
333 if (nSelectionStart
< 0 || nSelectionEnd
< 0)
334 nSelectionStart
= nSelectionEnd
= m_nCaretPosition
;
336 boost::property_tree::ptree aPayloadTree
;
337 aPayloadTree
.put("content", m_sFocusedParagraph
.toUtf8().getStr());
338 aPayloadTree
.put("start", nSelectionStart
);
339 aPayloadTree
.put("end", nSelectionEnd
);
340 std::stringstream aStream
;
341 boost::property_tree::write_json(aStream
, aPayloadTree
);
342 std::string aPayload
= aStream
.str();
343 OUString sRet
= OUString::fromUtf8(aPayload
);
347 int LOKDocumentFocusListener::getCaretPosition() const
349 SAL_INFO("lok.a11y", "LOKDocumentFocusListener::getCaretPosition: " << m_nCaretPosition
);
350 return m_nCaretPosition
;
353 void LOKDocumentFocusListener::notifyFocusedParagraphChanged()
355 boost::property_tree::ptree aPayloadTree
;
356 aPayloadTree
.put("content", m_sFocusedParagraph
.toUtf8().getStr());
357 aPayloadTree
.put("position", m_nCaretPosition
);
358 std::stringstream aStream
;
359 boost::property_tree::write_json(aStream
, aPayloadTree
);
360 std::string aPayload
= aStream
.str();
363 SAL_INFO("lok.a11y", "LOKDocumentFocusListener::notifyFocusedParagraphChanged: " << m_sFocusedParagraph
);
364 m_bFocusedParagraphNotified
= true;
365 const char* pPayload
= aPayload
.c_str();
366 m_pViewShell
->libreOfficeKitViewCallback(LOK_CALLBACK_A11Y_FOCUS_CHANGED
, pPayload
);
370 void LOKDocumentFocusListener::notifyCaretChanged()
372 boost::property_tree::ptree aPayloadTree
;
373 aPayloadTree
.put("position", m_nCaretPosition
);
374 std::stringstream aStream
;
375 boost::property_tree::write_json(aStream
, aPayloadTree
);
376 std::string aPayload
= aStream
.str();
379 SAL_INFO("lok.a11y", "LOKDocumentFocusListener::notifyCaretChanged: " << m_nCaretPosition
);
380 const char* pPayload
= aPayload
.c_str();
381 m_pViewShell
->libreOfficeKitViewCallback(LOK_CALLBACK_A11Y_CARET_CHANGED
, pPayload
);
385 void LOKDocumentFocusListener::notifyTextSelectionChanged()
387 boost::property_tree::ptree aPayloadTree
;
388 aPayloadTree
.put("start", m_nSelectionStart
);
389 aPayloadTree
.put("end", m_nSelectionEnd
);
390 std::stringstream aStream
;
391 boost::property_tree::write_json(aStream
, aPayloadTree
);
392 std::string aPayload
= aStream
.str();
395 SAL_INFO("lok.a11y", "LOKDocumentFocusListener::notifyTextSelectionChanged: start: " << m_nSelectionStart
<< ", end: " << m_nSelectionEnd
);
396 const char* pPayload
= aPayload
.c_str();
397 m_pViewShell
->libreOfficeKitViewCallback(LOK_CALLBACK_A11Y_TEXT_SELECTION_CHANGED
, pPayload
);
401 void LOKDocumentFocusListener::disposing( const lang::EventObject
& aEvent
)
403 // Unref the object here, but do not remove as listener since the object
404 // might no longer be in a state that safely allows this.
405 if( aEvent
.Source
.is() )
406 m_aRefList
.erase(aEvent
.Source
);
412 bool hasState(const accessibility::AccessibleEventObject
& aEvent
, ::sal_Int64 nState
)
415 uno::Reference
< accessibility::XAccessibleContext
> xContext(aEvent
.Source
, uno::UNO_QUERY
);
418 ::sal_Int64 nStateSet
= xContext
->getAccessibleStateSet();
419 res
= (nStateSet
& nState
) != 0;
424 bool isFocused(const accessibility::AccessibleEventObject
& aEvent
)
426 return hasState(aEvent
, accessibility::AccessibleStateType::FOCUSED
);
428 } // anonymous namespace
430 void LOKDocumentFocusListener::notifyEvent( const accessibility::AccessibleEventObject
& aEvent
)
434 switch( aEvent
.EventId
)
436 case accessibility::AccessibleEventId::STATE_CHANGED
:
438 uno::Reference
< accessibility::XAccessible
> xAccStateChanged
= getAccessible(aEvent
);
439 sal_Int64 nState
= accessibility::AccessibleStateType::INVALID
;
440 aEvent
.NewValue
>>= nState
;
441 SAL_INFO("lok.a11y", "LOKDocumentFocusListener::notifyEvent: STATE_CHANGED: XAccessible: " << xAccStateChanged
.get() << ", nState: " << nState
);
443 if( accessibility::AccessibleStateType::FOCUSED
== nState
)
445 SAL_INFO("lok.a11y", "LOKDocumentFocusListener::notifyEvent: FOCUSED");
447 if (m_bIsEditingCell
)
449 if (!hasState(aEvent
, accessibility::AccessibleStateType::ACTIVE
))
452 "LOKDocumentFocusListener::notifyEvent: FOCUSED: Cell not ACTIVE for editing yet");
456 uno::Reference
<css::accessibility::XAccessibleText
> xAccText(xAccStateChanged
, uno::UNO_QUERY
);
459 OUString sText
= xAccText
->getText();
460 sal_Int32 nLength
= sText
.getLength();
461 sal_Int32 nCaretPosition
= xAccText
->getCaretPosition();
462 SAL_INFO("lok.a11y", "LOKDocumentFocusListener::notifyEvent: xAccText: " << xAccText
.get()
463 << ", text: >" << sText
<< "<, caret pos: " << nCaretPosition
);
467 css::uno::Reference
<css::accessibility::XAccessibleTextAttributes
>
468 xAccTextAttr(xAccText
, uno::UNO_QUERY
);
469 css::uno::Sequence
< OUString
> aRequestedAttributes
;
472 while (nPos
< nLength
)
474 css::accessibility::TextSegment aTextSegment
=
475 xAccText
->getTextAtIndex(nPos
, css::accessibility::AccessibleTextType::ATTRIBUTE_RUN
);
476 SAL_INFO("lok.a11y", "LOKDocumentFocusListener::notifyEvent: "
477 "text segment: '" << aTextSegment
.SegmentText
478 << "', start: " << aTextSegment
.SegmentStart
479 << ", end: " << aTextSegment
.SegmentEnd
);
481 css::uno::Sequence
< css::beans::PropertyValue
> aRunAttributeList
;
482 if (xAccTextAttr
.is())
484 aRunAttributeList
= xAccTextAttr
->getRunAttributes(nPos
, aRequestedAttributes
);
488 aRunAttributeList
= xAccText
->getCharacterAttributes(nPos
, aRequestedAttributes
);
491 sal_Int32 nSize
= aRunAttributeList
.getLength();
493 "LOKDocumentFocusListener::notifyEvent: attribute list size: " << nSize
);
497 OUString sAttributes
= "{ ";
498 for (const auto& attribute
: aRunAttributeList
)
500 if (attribute
.Name
.isEmpty())
503 if (attribute
.Name
== "CharHeight" || attribute
.Name
== "CharWeight")
506 attribute
.Value
>>= fValue
;
507 sValue
= OUString::number(fValue
);
509 else if (attribute
.Name
== "CharPosture")
511 awt::FontSlant nValue
;
512 attribute
.Value
>>= nValue
;
513 sValue
= OUString::number(static_cast<unsigned int>(nValue
));
515 else if (attribute
.Name
== "CharUnderline")
518 attribute
.Value
>>= nValue
;
519 sValue
= OUString::number(nValue
);
521 else if (attribute
.Name
== "CharFontName")
523 attribute
.Value
>>= sValue
;
525 else if (attribute
.Name
== "Rsid")
527 sal_uInt32
nValue(0);
528 attribute
.Value
>>= nValue
;
529 sValue
= OUString::number(nValue
);
532 if (!sValue
.isEmpty())
534 if (sAttributes
!= "{ ")
536 sAttributes
+= attribute
.Name
+ ": " + sValue
;
542 "LOKDocumentFocusListener::notifyEvent: attributes: " << sAttributes
);
544 nPos
= aTextSegment
.SegmentEnd
+ 1;
547 if (!m_bFocusedParagraphNotified
|| m_sFocusedParagraph
!= sText
)
549 m_sFocusedParagraph
= sText
;
550 m_nCaretPosition
= nCaretPosition
;
551 notifyFocusedParagraphChanged();
559 case accessibility::AccessibleEventId::CARET_CHANGED
:
561 if (!isFocused(aEvent
))
564 "LOKDocumentFocusListener::notifyEvent: CARET_CHANGED: skip non focused paragraph");
568 sal_Int32 nNewPos
= -1;
569 aEvent
.NewValue
>>= nNewPos
;
570 sal_Int32 nOldPos
= -1;
571 aEvent
.OldValue
>>= nOldPos
;
575 SAL_INFO("lok.a11y", "LOKDocumentFocusListener::notifyEvent: CARET_CHANGED: new pos: " << nNewPos
<< ", nOldPos: " << nOldPos
);
576 uno::Reference
<css::accessibility::XAccessibleText
>
577 xAccText(getAccessible(aEvent
), uno::UNO_QUERY
);
580 OUString sText
= xAccText
->getText();
581 SAL_INFO("lok.a11y", "LOKDocumentFocusListener::notifyEvent: CARET_CHANGED: xAccText: " << xAccText
.get() << ", text: >" << sText
<< "<");
583 m_nCaretPosition
= nNewPos
;
584 m_nSelectionStart
= m_nSelectionEnd
= m_nCaretPosition
;
585 notifyCaretChanged();
592 case accessibility::AccessibleEventId::TEXT_CHANGED
:
594 if (!isFocused(aEvent
))
597 "LOKDocumentFocusListener::notifyEvent: TEXT_CHANGED: skip non focused paragraph");
601 accessibility::TextSegment aDeletedText
;
602 accessibility::TextSegment aInsertedText
;
604 if (aEvent
.OldValue
>>= aDeletedText
)
606 SAL_INFO("lok.a11y", "LOKDocumentFocusListener::notifyEvent: TEXT_CHANGED: deleted text: >" << aDeletedText
.SegmentText
<< "<");
608 if (aEvent
.NewValue
>>= aInsertedText
)
610 SAL_INFO("lok.a11y", "LOKDocumentFocusListener::notifyEvent: TEXT_CHANGED: inserted text: >" << aInsertedText
.SegmentText
<< "<");
612 uno::Reference
<css::accessibility::XAccessibleText
> xAccText(getAccessible(aEvent
), uno::UNO_QUERY
);
615 OUString sText
= xAccText
->getText();
616 SAL_INFO("lok.a11y", "LOKDocumentFocusListener::notifyEvent: TEXT_CHANGED: "
617 "xAccText: " << xAccText
.get() << ", text: >" << sText
<< "<");
618 m_sFocusedParagraph
= sText
;
619 m_bFocusedParagraphNotified
= false;
624 case accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED
:
626 if (!isFocused(aEvent
))
629 "LOKDocumentFocusListener::notifyEvent: TEXT_SELECTION_CHANGED: skip non focused paragraph");
633 uno::Reference
<css::accessibility::XAccessibleText
> xAccText(getAccessible(aEvent
), uno::UNO_QUERY
);
636 OUString sText
= xAccText
->getText();
637 sal_Int32 nSelectionStart
= xAccText
->getSelectionStart();
638 sal_Int32 nSelectionEnd
= xAccText
->getSelectionEnd();
639 m_sSelectedText
= xAccText
->getSelectedText();
641 SAL_INFO("lok.a11y", "LOKDocumentFocusListener::notifyEvent: TEXT_SELECTION_CHANGED: "
642 "\n xAccText: " << xAccText
.get() << ", text: >" << sText
<< "<"
643 "\n start: " << nSelectionStart
<< ", end: " << nSelectionEnd
644 << "\n selected text: >" << m_sSelectedText
<< "<");
646 // This should not be risky since selection start/end are set also on CARET_CHANGED event
647 if (nSelectionStart
== m_nSelectionStart
&& nSelectionEnd
== m_nSelectionEnd
)
650 // We send a message to client also when start/end are -1, in this way the client knows
651 // if a text selection object exists or not. That's needed because of the odd behavior
652 // occurring when <backspace>/<delete> are hit and a text selection is empty but it still exists.
653 // Such keys delete the empty selection instead of the previous/next char.
654 m_nSelectionStart
= nSelectionStart
;
655 m_nSelectionEnd
= nSelectionEnd
;
657 // Calc: when editing a formula send the update content
658 if (m_bIsEditingCell
&& !m_sSelectedCellAddress
.isEmpty()
659 && !m_sSelectedText
.isEmpty() && sText
.startsWith("="))
661 notifyFocusedParagraphChanged();
663 notifyTextSelectionChanged();
668 case accessibility::AccessibleEventId::SELECTION_CHANGED
:
670 uno::Reference
< accessibility::XAccessible
> xNewValue
;
671 aEvent
.NewValue
>>= xNewValue
;
674 uno::Reference
< accessibility::XAccessibleContext
> xContext
=
675 xNewValue
->getAccessibleContext();
679 OUString sName
= xContext
->getAccessibleName();
680 SAL_INFO("lok.a11y", "LOKDocumentFocusListener::notifyEvent: SELECTION_CHANGED: this: " << this
681 << ", selected cell address: >" << sName
<< "<"
682 ", m_bIsEditingCell: " << m_bIsEditingCell
);
683 if (m_bIsEditingCell
&& !sName
.isEmpty())
685 m_sSelectedCellAddress
= sName
;
686 // Check cell address: "$Sheet1.A10".
687 // On cell editing SELECTION_CHANGED is not emitted when selection is expanded.
688 // So selection can't be a cell range.
689 sal_Int32 nDotIndex
= m_sSelectedText
.indexOf('.');
690 OUString sCellAddress
= m_sSelectedText
.copy(nDotIndex
+ 1);
691 SAL_INFO("lok.a11y", "LOKDocumentFocusListener::notifyEvent: SELECTION_CHANGED: "
692 "cell address: >" << sCellAddress
<< "<");
693 if (m_sSelectedCellAddress
== sCellAddress
)
695 notifyFocusedParagraphChanged();
696 notifyTextSelectionChanged();
703 case accessibility::AccessibleEventId::CHILD
:
705 uno::Reference
< accessibility::XAccessible
> xChild
;
706 if( (aEvent
.OldValue
>>= xChild
) && xChild
.is() )
707 detachRecursive(xChild
);
709 if( (aEvent
.NewValue
>>= xChild
) && xChild
.is() )
710 attachRecursive(xChild
);
715 case accessibility::AccessibleEventId::INVALIDATE_ALL_CHILDREN
:
716 SAL_INFO("lok.a11y", "Invalidate all children called");
723 catch( const lang::IndexOutOfBoundsException
& )
725 SAL_WARN("lok.a11y", "Focused object has invalid index in parent");
729 uno::Reference
< accessibility::XAccessible
> LOKDocumentFocusListener::getAccessible(const lang::EventObject
& aEvent
)
731 uno::Reference
< accessibility::XAccessible
> xAccessible(aEvent
.Source
, uno::UNO_QUERY
);
733 if( xAccessible
.is() )
736 uno::Reference
< accessibility::XAccessibleContext
> xContext(aEvent
.Source
, uno::UNO_QUERY
);
740 uno::Reference
< accessibility::XAccessible
> xParent( xContext
->getAccessibleParent() );
743 uno::Reference
< accessibility::XAccessibleContext
> xParentContext( xParent
->getAccessibleContext() );
744 if( xParentContext
.is() )
746 return xParentContext
->getAccessibleChild( xContext
->getAccessibleIndexInParent() );
751 return uno::Reference
< accessibility::XAccessible
>();
754 void LOKDocumentFocusListener::attachRecursive(
755 const uno::Reference
< accessibility::XAccessible
>& xAccessible
758 SAL_INFO("lok.a11y", "LOKDocumentFocusListener::attachRecursive(1): xAccessible: " << xAccessible
.get());
760 uno::Reference
< accessibility::XAccessibleContext
> xContext
=
761 xAccessible
->getAccessibleContext();
764 attachRecursive(xAccessible
, xContext
);
767 void LOKDocumentFocusListener::attachRecursive(
768 const uno::Reference
< accessibility::XAccessible
>& xAccessible
,
769 const uno::Reference
< accessibility::XAccessibleContext
>& xContext
772 SAL_INFO("lok.a11y", "LOKDocumentFocusListener::attachRecursive(2): xAccessible: " << xAccessible
.get()
773 << ", role: " << xContext
->getAccessibleRole()
774 << ", name: " << xContext
->getAccessibleName()
775 << ", parent: " << xContext
->getAccessibleParent().get()
776 << ", child count: " << xContext
->getAccessibleChildCount());
778 sal_Int64 nStateSet
= xContext
->getAccessibleStateSet();
780 if (!m_bIsEditingCell
)
782 ::rtl::OUString sName
= xContext
->getAccessibleName();
783 m_bIsEditingCell
= sName
.startsWith("Cell");
786 attachRecursive(xAccessible
, xContext
, nStateSet
);
789 void LOKDocumentFocusListener::attachRecursive(
790 const uno::Reference
< accessibility::XAccessible
>& xAccessible
,
791 const uno::Reference
< accessibility::XAccessibleContext
>& xContext
,
792 const sal_Int64 nStateSet
795 SAL_INFO("lok.a11y", "LOKDocumentFocusListener::attachRecursive(3) #1: this: " << this
796 << ", xAccessible: " << xAccessible
.get()
797 << ", role: " << xContext
->getAccessibleRole()
798 << ", name: " << xContext
->getAccessibleName()
799 << ", parent: " << xContext
->getAccessibleParent().get()
800 << ", child count: " << xContext
->getAccessibleChildCount());
802 uno::Reference
< accessibility::XAccessibleEventBroadcaster
> xBroadcaster(xContext
, uno::UNO_QUERY
);
804 if (!xBroadcaster
.is())
806 SAL_INFO("lok.a11y", "LOKDocumentFocusListener::attachRecursive(3) #2: xBroadcaster.is()");
807 // If not already done, add the broadcaster to the list and attach as listener.
808 const uno::Reference
< uno::XInterface
>& xInterface
= xBroadcaster
;
809 if( m_aRefList
.insert(xInterface
).second
)
811 SAL_INFO("lok.a11y", "LOKDocumentFocusListener::attachRecursive(3) #3: m_aRefList.insert(xInterface).second");
812 xBroadcaster
->addAccessibleEventListener(static_cast< accessibility::XAccessibleEventListener
*>(this));
815 if( !(nStateSet
& accessibility::AccessibleStateType::MANAGES_DESCENDANTS
) )
817 sal_Int64 nmax
= xContext
->getAccessibleChildCount();
818 if( nmax
> MAX_ATTACHABLE_CHILDREN
)
819 nmax
= MAX_ATTACHABLE_CHILDREN
;
821 for( sal_Int64 n
= 0; n
< nmax
; n
++ )
823 uno::Reference
< accessibility::XAccessible
> xChild( xContext
->getAccessibleChild( n
) );
826 attachRecursive(xChild
);
832 void LOKDocumentFocusListener::detachRecursive(
833 const uno::Reference
< accessibility::XAccessible
>& xAccessible
836 uno::Reference
< accessibility::XAccessibleContext
> xContext
=
837 xAccessible
->getAccessibleContext();
840 detachRecursive(xContext
);
843 void LOKDocumentFocusListener::detachRecursive(
844 const uno::Reference
< accessibility::XAccessibleContext
>& xContext
847 sal_Int64 nStateSet
= xContext
->getAccessibleStateSet();
849 SAL_INFO("lok.a11y", "LOKDocumentFocusListener::detachRecursive(2): this: " << this
850 << ", name: " << xContext
->getAccessibleName()
851 << ", parent: " << xContext
->getAccessibleParent().get()
852 << ", child count: " << xContext
->getAccessibleChildCount());
854 if (m_bIsEditingCell
)
856 ::rtl::OUString sName
= xContext
->getAccessibleName();
857 m_bIsEditingCell
= !sName
.startsWith("Cell");
858 if (!m_bIsEditingCell
)
860 m_sFocusedParagraph
= "";
861 m_nCaretPosition
= 0;
862 notifyFocusedParagraphChanged();
866 detachRecursive(xContext
, nStateSet
);
869 void LOKDocumentFocusListener::detachRecursive(
870 const uno::Reference
< accessibility::XAccessibleContext
>& xContext
,
871 const sal_Int64 nStateSet
874 uno::Reference
< accessibility::XAccessibleEventBroadcaster
> xBroadcaster(xContext
, uno::UNO_QUERY
);
876 if( xBroadcaster
.is() && 0 < m_aRefList
.erase(xBroadcaster
) )
878 xBroadcaster
->removeAccessibleEventListener(static_cast< accessibility::XAccessibleEventListener
*>(this));
880 if( !( nStateSet
& accessibility::AccessibleStateType::MANAGES_DESCENDANTS
) )
882 sal_Int64 nmax
= xContext
->getAccessibleChildCount();
883 if( nmax
> MAX_ATTACHABLE_CHILDREN
)
884 nmax
= MAX_ATTACHABLE_CHILDREN
;
886 for( sal_Int64 n
= 0; n
< nmax
; n
++ )
888 uno::Reference
< accessibility::XAccessible
> xChild( xContext
->getAccessibleChild( n
) );
891 detachRecursive(xChild
);
897 sal_uInt32
SfxViewShell_Impl::m_nLastViewShellId
= 0;
899 SfxViewShell_Impl::SfxViewShell_Impl(SfxViewShellFlags
const nFlags
, ViewShellDocId nDocId
)
900 : m_bHasPrintOptions(nFlags
& SfxViewShellFlags::HAS_PRINTOPTIONS
)
901 , m_nFamily(0xFFFF) // undefined, default set by TemplateDialog
902 , m_pLibreOfficeKitViewCallback(nullptr)
903 , m_bTiledSearching(false)
904 , m_nViewShellId(SfxViewShell_Impl::m_nLastViewShellId
++)
909 SfxViewShell_Impl::~SfxViewShell_Impl()
913 std::vector
< SfxInPlaceClient
* >& SfxViewShell_Impl::GetIPClients_Impl()
918 SFX_IMPL_SUPERCLASS_INTERFACE(SfxViewShell
,SfxShell
)
920 void SfxViewShell::InitInterface_Impl()
925 /** search for a filter name dependent on type and module
927 static OUString
impl_retrieveFilterNameFromTypeAndModule(
928 const css::uno::Reference
< css::container::XContainerQuery
>& rContainerQuery
,
929 const OUString
& rType
,
930 const OUString
& rModuleIdentifier
,
931 const sal_Int32 nFlags
)
933 // Retrieve filter from type
934 css::uno::Sequence
< css::beans::NamedValue
> aQuery
{
935 { "Type", css::uno::Any( rType
) },
936 { "DocumentService", css::uno::Any( rModuleIdentifier
) }
939 css::uno::Reference
< css::container::XEnumeration
> xEnumeration
=
940 rContainerQuery
->createSubSetEnumerationByProperties( aQuery
);
942 OUString aFoundFilterName
;
943 while ( xEnumeration
->hasMoreElements() )
945 ::comphelper::SequenceAsHashMap
aFilterPropsHM( xEnumeration
->nextElement() );
946 OUString aFilterName
= aFilterPropsHM
.getUnpackedValueOrDefault(
950 sal_Int32 nFilterFlags
= aFilterPropsHM
.getUnpackedValueOrDefault(
954 if ( nFilterFlags
& nFlags
)
956 aFoundFilterName
= aFilterName
;
961 return aFoundFilterName
;
966 /** search for an internal typename, which map to the current app module
967 and map also to a "family" of file formats as e.g. PDF/MS Doc/OOo Doc.
977 static OUString
impl_searchFormatTypeForApp(const css::uno::Reference
< css::frame::XFrame
>& xFrame
,
978 ETypeFamily eTypeFamily
)
982 css::uno::Reference
< css::uno::XComponentContext
> xContext (::comphelper::getProcessComponentContext());
983 css::uno::Reference
< css::frame::XModuleManager2
> xModuleManager(css::frame::ModuleManager::create(xContext
));
985 OUString sModule
= xModuleManager
->identify(xFrame
);
992 if ( sModule
== "com.sun.star.text.TextDocument" )
993 sType
= "writer_MS_Word_2007";
995 if ( sModule
== "com.sun.star.sheet.SpreadsheetDocument" )
996 sType
= "MS Excel 2007 XML";
998 if ( sModule
== "com.sun.star.presentation.PresentationDocument" )
999 sType
= "MS PowerPoint 2007 XML";
1005 if ( sModule
== "com.sun.star.text.TextDocument" )
1008 if ( sModule
== "com.sun.star.sheet.SpreadsheetDocument" )
1011 if ( sModule
== "com.sun.star.drawing.DrawingDocument" )
1014 if ( sModule
== "com.sun.star.presentation.PresentationDocument" )
1022 catch (const css::uno::RuntimeException
&)
1026 catch (const css::uno::Exception
&)
1033 void SfxViewShell::NewIPClient_Impl( SfxInPlaceClient
*pIPClient
)
1035 pImpl
->GetIPClients_Impl().push_back(pIPClient
);
1038 void SfxViewShell::IPClientGone_Impl( SfxInPlaceClient
const *pIPClient
)
1040 std::vector
< SfxInPlaceClient
* >& pClients
= pImpl
->GetIPClients_Impl();
1042 auto it
= std::find(pClients
.begin(), pClients
.end(), pIPClient
);
1043 if (it
!= pClients
.end())
1044 pClients
.erase( it
);
1048 void SfxViewShell::ExecMisc_Impl( SfxRequest
&rReq
)
1050 const sal_uInt16 nId
= rReq
.GetSlot();
1053 case SID_STYLE_FAMILY
:
1055 const SfxUInt16Item
* pItem
= rReq
.GetArg
<SfxUInt16Item
>(nId
);
1058 pImpl
->m_nFamily
= pItem
->GetValue();
1062 case SID_ACTIVATE_STYLE_APPLY
:
1064 uno::Reference
< frame::XFrame
> xFrame
=
1065 GetViewFrame().GetFrame().GetFrameInterface();
1067 Reference
< beans::XPropertySet
> xPropSet( xFrame
, UNO_QUERY
);
1068 Reference
< frame::XLayoutManager
> xLayoutManager
;
1069 if ( xPropSet
.is() )
1073 Any aValue
= xPropSet
->getPropertyValue("LayoutManager");
1074 aValue
>>= xLayoutManager
;
1075 if ( xLayoutManager
.is() )
1077 uno::Reference
< ui::XUIElement
> xElement
= xLayoutManager
->getElement( "private:resource/toolbar/textobjectbar" );
1080 xElement
= xLayoutManager
->getElement( "private:resource/toolbar/frameobjectbar" );
1084 xElement
= xLayoutManager
->getElement( "private:resource/toolbar/oleobjectbar" );
1088 uno::Reference
< awt::XWindow
> xWin( xElement
->getRealInterface(), uno::UNO_QUERY_THROW
);
1089 VclPtr
<vcl::Window
> pWin
= VCLUnoHelper::GetWindow( xWin
);
1090 ToolBox
* pTextToolbox
= dynamic_cast< ToolBox
* >( pWin
.get() );
1093 ToolBox::ImplToolItems::size_type nItemCount
= pTextToolbox
->GetItemCount();
1094 for( ToolBox::ImplToolItems::size_type nItem
= 0; nItem
< nItemCount
; ++nItem
)
1096 ToolBoxItemId nItemId
= pTextToolbox
->GetItemId( nItem
);
1097 const OUString
& rCommand
= pTextToolbox
->GetItemCommand( nItemId
);
1098 if (rCommand
== ".uno:StyleApply")
1100 vcl::Window
* pItemWin
= pTextToolbox
->GetItemWindow( nItemId
);
1102 pItemWin
->GrabFocus();
1110 catch (const Exception
&)
1118 case SID_MAIL_SENDDOCASMS
:
1119 case SID_MAIL_SENDDOCASOOO
:
1120 case SID_MAIL_SENDDOCASPDF
:
1121 case SID_MAIL_SENDDOC
:
1122 case SID_MAIL_SENDDOCASFORMAT
:
1124 SfxObjectShell
* pDoc
= GetObjectShell();
1125 if ( pDoc
&& pDoc
->QueryHiddenInformation(
1126 HiddenWarningFact::WhenSaving
, GetViewFrame().GetFrameWeld() ) != RET_YES
)
1130 SfxMailModel aModel
;
1133 const SfxStringItem
* pMailRecipient
= rReq
.GetArg
<SfxStringItem
>(SID_MAIL_RECIPIENT
);
1134 if ( pMailRecipient
)
1136 OUString
aRecipient( pMailRecipient
->GetValue() );
1137 OUString
aMailToStr("mailto:");
1139 if ( aRecipient
.startsWith( aMailToStr
) )
1140 aRecipient
= aRecipient
.copy( aMailToStr
.getLength() );
1141 aModel
.AddToAddress( aRecipient
);
1143 const SfxStringItem
* pMailDocType
= rReq
.GetArg
<SfxStringItem
>(SID_TYPE_NAME
);
1145 aDocType
= pMailDocType
->GetValue();
1147 uno::Reference
< frame::XFrame
> xFrame( rFrame
.GetFrame().GetFrameInterface() );
1148 SfxMailModel::SendMailResult eResult
= SfxMailModel::SEND_MAIL_ERROR
;
1150 if ( nId
== SID_MAIL_SENDDOC
)
1151 eResult
= aModel
.SaveAndSend( xFrame
, OUString() );
1152 else if ( nId
== SID_MAIL_SENDDOCASPDF
)
1153 eResult
= aModel
.SaveAndSend( xFrame
, "pdf_Portable_Document_Format");
1154 else if ( nId
== SID_MAIL_SENDDOCASMS
)
1156 aDocType
= impl_searchFormatTypeForApp(xFrame
, E_MS_DOC
);
1157 if (!aDocType
.isEmpty())
1158 eResult
= aModel
.SaveAndSend( xFrame
, aDocType
);
1160 else if ( nId
== SID_MAIL_SENDDOCASOOO
)
1162 aDocType
= impl_searchFormatTypeForApp(xFrame
, E_OOO_DOC
);
1163 if (!aDocType
.isEmpty())
1164 eResult
= aModel
.SaveAndSend( xFrame
, aDocType
);
1167 if ( eResult
== SfxMailModel::SEND_MAIL_ERROR
)
1169 weld::Window
* pWin
= SfxGetpApp()->GetTopWindow();
1170 std::unique_ptr
<weld::MessageDialog
> xBox(Application::CreateMessageDialog(pWin
,
1171 VclMessageType::Info
, VclButtonsType::Ok
,
1172 SfxResId(STR_ERROR_SEND_MAIL
)));
1181 case SID_BLUETOOTH_SENDDOC
:
1183 SfxBluetoothModel aModel
;
1184 SfxObjectShell
* pDoc
= GetObjectShell();
1185 if ( pDoc
&& pDoc
->QueryHiddenInformation(
1186 HiddenWarningFact::WhenSaving
, GetViewFrame().GetFrameWeld() ) != RET_YES
)
1188 uno::Reference
< frame::XFrame
> xFrame( rFrame
.GetFrame().GetFrameInterface() );
1189 SfxMailModel::SendMailResult eResult
= aModel
.SaveAndSend( xFrame
);
1190 if( eResult
== SfxMailModel::SEND_MAIL_ERROR
)
1192 weld::Window
* pWin
= SfxGetpApp()->GetTopWindow();
1193 std::unique_ptr
<weld::MessageDialog
> xBox(Application::CreateMessageDialog(pWin
,
1194 VclMessageType::Info
, VclButtonsType::Ok
,
1195 SfxResId(STR_ERROR_SEND_MAIL
)));
1204 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1207 css::uno::Reference
< lang::XMultiServiceFactory
> xSMGR(::comphelper::getProcessServiceFactory(), css::uno::UNO_SET_THROW
);
1208 css::uno::Reference
< uno::XComponentContext
> xContext(::comphelper::getProcessComponentContext(), css::uno::UNO_SET_THROW
);
1209 css::uno::Reference
< css::frame::XFrame
> xFrame( rFrame
.GetFrame().GetFrameInterface() );
1210 css::uno::Reference
< css::frame::XModel
> xModel
;
1212 css::uno::Reference
< css::frame::XModuleManager2
> xModuleManager( css::frame::ModuleManager::create(xContext
) );
1217 aModule
= xModuleManager
->identify( xFrame
);
1219 catch (const css::uno::RuntimeException
&)
1223 catch (const css::uno::Exception
&)
1229 css::uno::Reference
< css::frame::XController
> xController
= xFrame
->getController();
1230 if ( xController
.is() )
1231 xModel
= xController
->getModel();
1234 // We need at least a valid module name and model reference
1235 css::uno::Reference
< css::frame::XStorable
> xStorable( xModel
, css::uno::UNO_QUERY
);
1236 if ( xModel
.is() && xStorable
.is() )
1238 OUString aFilterName
;
1239 OUString
aTypeName( "generic_HTML" );
1242 OUString aLocation
= xStorable
->getLocation();
1243 INetURLObject
aFileObj( aLocation
);
1245 bool bPrivateProtocol
= ( aFileObj
.GetProtocol() == INetProtocol::PrivSoffice
);
1246 bool bHasLocation
= !aLocation
.isEmpty() && !bPrivateProtocol
;
1248 css::uno::Reference
< css::container::XContainerQuery
> xContainerQuery(
1249 xSMGR
->createInstance( "com.sun.star.document.FilterFactory" ),
1250 css::uno::UNO_QUERY_THROW
);
1252 // Retrieve filter from type
1254 sal_Int32 nFilterFlags
= 0x00000002; // export
1255 aFilterName
= impl_retrieveFilterNameFromTypeAndModule( xContainerQuery
, aTypeName
, aModule
, nFilterFlags
);
1256 if ( aFilterName
.isEmpty() )
1258 // Draw/Impress uses a different type. 2nd chance try to use alternative type name
1259 aFilterName
= impl_retrieveFilterNameFromTypeAndModule(
1260 xContainerQuery
, "graphic_HTML", aModule
, nFilterFlags
);
1263 // No filter found => error
1264 // No type and no location => error
1265 if ( aFilterName
.isEmpty() || aTypeName
.isEmpty())
1271 // Use provided save file name. If empty determine file name
1272 if ( !bHasLocation
)
1274 // Create a default file name with the correct extension
1275 aFileName
= "webpreview";
1279 // Determine file name from model
1280 INetURLObject
aFObj( xStorable
->getLocation() );
1281 aFileName
= aFObj
.getName( INetURLObject::LAST_SEGMENT
, true, INetURLObject::DecodeMechanism::NONE
);
1284 OSL_ASSERT( !aFilterName
.isEmpty() );
1285 OSL_ASSERT( !aFileName
.isEmpty() );
1287 // Creates a temporary directory to store our predefined file into it (for the
1288 // flatpak case, create it in XDG_CACHE_HOME instead of /tmp for technical reasons,
1289 // so that it can be accessed by the browser running outside the sandbox):
1290 OUString
* parent
= nullptr;
1291 if (flatpak::isFlatpak() && !flatpak::createTemporaryHtmlDirectory(&parent
))
1293 SAL_WARN("sfx.view", "cannot create Flatpak html temp dir");
1296 INetURLObject
aFilePathObj( ::utl::CreateTempURL(parent
, true) );
1297 aFilePathObj
.insertName( aFileName
);
1298 aFilePathObj
.setExtension( u
"htm" );
1300 OUString aFileURL
= aFilePathObj
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
1302 css::uno::Sequence
< css::beans::PropertyValue
> aArgs
{
1303 comphelper::makePropertyValue("FilterName", aFilterName
)
1306 // Store document in the html format
1309 xStorable
->storeToURL( aFileURL
, aArgs
);
1311 catch (const io::IOException
&)
1317 sfx2::openUriExternally(aFileURL
, true, rReq
.GetFrameWeld());
1331 void SfxViewShell::GetState_Impl( SfxItemSet
&rSet
)
1334 SfxWhichIter
aIter( rSet
);
1335 SfxObjectShell
*pSh
= GetViewFrame().GetObjectShell();
1336 for ( sal_uInt16 nSID
= aIter
.FirstWhich(); nSID
; nSID
= aIter
.NextWhich() )
1341 case SID_BLUETOOTH_SENDDOC
:
1342 case SID_MAIL_SENDDOC
:
1343 case SID_MAIL_SENDDOCASFORMAT
:
1344 case SID_MAIL_SENDDOCASMS
:
1345 case SID_MAIL_SENDDOCASOOO
:
1346 case SID_MAIL_SENDDOCASPDF
:
1348 #if HAVE_FEATURE_MACOSX_SANDBOX
1349 rSet
.DisableItem(nSID
);
1351 if (pSh
&& pSh
->isExportLocked())
1352 rSet
.DisableItem(nSID
);
1357 if (pSh
&& pSh
->isExportLocked())
1358 rSet
.DisableItem(nSID
);
1361 // Printer functions
1363 case SID_PRINTDOCDIRECT
:
1364 case SID_SETUPPRINTER
:
1365 case SID_PRINTER_NAME
:
1367 if (Application::GetSettings().GetMiscSettings().GetDisablePrinting()
1368 || (pSh
&& pSh
->isPrintLocked()))
1370 rSet
.DisableItem(nSID
);
1374 SfxPrinter
*pPrinter
= GetPrinter();
1376 if ( SID_PRINTDOCDIRECT
== nSID
)
1378 OUString aPrinterName
;
1379 if ( pPrinter
!= nullptr )
1380 aPrinterName
= pPrinter
->GetName();
1383 // tdf#109149 don't poll the Default Printer Name on every query.
1384 // We are queried on every change, so on every
1385 // keystroke, and we are only using this to fill in the
1386 // printername inside the label of "Print Directly (printer-name)"
1387 // On Printer::GetDefaultPrinterName() is implemented with
1388 // GetDefaultPrinter so don't call this excessively. 5 mins
1389 // seems a reasonable refresh time.
1390 std::chrono::steady_clock::time_point now
= std::chrono::steady_clock::now();
1391 std::chrono::minutes
five_mins(5);
1392 if (now
> pImpl
->m_nDefaultPrinterNameFetchTime
+ five_mins
)
1394 pImpl
->m_sDefaultPrinterName
= Printer::GetDefaultPrinterName();
1395 pImpl
->m_nDefaultPrinterNameFetchTime
= now
;
1397 aPrinterName
= pImpl
->m_sDefaultPrinterName
;
1399 if ( !aPrinterName
.isEmpty() )
1401 uno::Reference
< frame::XFrame
> xFrame( rFrame
.GetFrame().GetFrameInterface() );
1403 auto aProperties
= vcl::CommandInfoProvider::GetCommandProperties(".uno:PrintDefault",
1404 vcl::CommandInfoProvider::GetModuleIdentifier(xFrame
));
1405 OUString val
= vcl::CommandInfoProvider::GetLabelForCommand(aProperties
) +
1406 " (" + aPrinterName
+ ")";
1408 rSet
.Put( SfxStringItem( SID_PRINTDOCDIRECT
, val
) );
1413 case SID_STYLE_FAMILY
:
1415 rSet
.Put( SfxUInt16Item( SID_STYLE_FAMILY
, pImpl
->m_nFamily
) );
1422 void SfxViewShell::SetZoomFactor( const Fraction
&rZoomX
,
1423 const Fraction
&rZoomY
)
1425 DBG_ASSERT( GetWindow(), "no window" );
1426 MapMode
aMap( GetWindow()->GetMapMode() );
1427 aMap
.SetScaleX( rZoomX
);
1428 aMap
.SetScaleY( rZoomY
);
1429 GetWindow()->SetMapMode( aMap
);
1432 ErrCode
SfxViewShell::DoVerb(sal_Int32
/*nVerb*/)
1436 Virtual Method used to perform a Verb on a selected Object.
1437 Since this Object is only known by the derived classes, they must override
1442 return ERRCODE_SO_NOVERBS
;
1445 void SfxViewShell::OutplaceActivated( bool bActive
)
1448 GetFrame()->GetFrame().Appear();
1451 void SfxViewShell::UIActivating( SfxInPlaceClient
* /*pClient*/ )
1453 uno::Reference
< frame::XFrame
> xOwnFrame( rFrame
.GetFrame().GetFrameInterface() );
1454 uno::Reference
< frame::XFramesSupplier
> xParentFrame
= xOwnFrame
->getCreator();
1455 if ( xParentFrame
.is() )
1456 xParentFrame
->setActiveFrame( xOwnFrame
);
1458 rFrame
.GetBindings().HidePopups();
1459 rFrame
.GetDispatcher()->Update_Impl( true );
1462 void SfxViewShell::UIDeactivated( SfxInPlaceClient
* /*pClient*/ )
1464 if ( !rFrame
.GetFrame().IsClosing_Impl() || SfxViewFrame::Current() != &rFrame
)
1465 rFrame
.GetDispatcher()->Update_Impl( true );
1466 rFrame
.GetBindings().HidePopups(false);
1468 rFrame
.GetBindings().InvalidateAll(true);
1471 SfxInPlaceClient
* SfxViewShell::FindIPClient
1473 const uno::Reference
< embed::XEmbeddedObject
>& xObj
,
1474 vcl::Window
* pObjParentWin
1477 std::vector
< SfxInPlaceClient
* >& rClients
= pImpl
->GetIPClients_Impl();
1478 if ( rClients
.empty() )
1481 if( !pObjParentWin
)
1482 pObjParentWin
= GetWindow();
1483 for (SfxInPlaceClient
* pIPClient
: rClients
)
1485 if ( pIPClient
->GetObject() == xObj
&& pIPClient
->GetEditWin() == pObjParentWin
)
1493 SfxInPlaceClient
* SfxViewShell::GetIPClient() const
1495 return GetUIActiveClient();
1499 SfxInPlaceClient
* SfxViewShell::GetUIActiveIPClient_Impl() const
1501 // this method is needed as long as SFX still manages the border space for ChildWindows (see SfxFrame::Resize)
1502 std::vector
< SfxInPlaceClient
* >& rClients
= pImpl
->GetIPClients_Impl();
1503 if ( rClients
.empty() )
1506 for (SfxInPlaceClient
* pIPClient
: rClients
)
1508 if ( pIPClient
->IsUIActive() )
1515 SfxInPlaceClient
* SfxViewShell::GetUIActiveClient() const
1517 std::vector
< SfxInPlaceClient
* >& rClients
= pImpl
->GetIPClients_Impl();
1518 if ( rClients
.empty() )
1521 const bool bIsTiledRendering
= comphelper::LibreOfficeKit::isActive();
1523 for (SfxInPlaceClient
* pIPClient
: rClients
)
1525 if ( pIPClient
->IsObjectUIActive() || ( bIsTiledRendering
&& pIPClient
->IsObjectInPlaceActive() ) )
1533 void SfxViewShell::Activate( bool bMDI
)
1537 SfxObjectShell
*pSh
= GetViewFrame().GetObjectShell();
1538 if (const auto xModel
= pSh
->GetModel())
1539 xModel
->setCurrentController(GetController());
1541 SetCurrentDocument();
1546 void SfxViewShell::Deactivate(bool /*bMDI*/)
1551 void SfxViewShell::Move()
1555 This virtual Method is called when the window displayed in the
1556 SfxViewShell gets a StarView-Move() notification.
1558 This base implementation does not have to be called. .
1562 This Method can be used to cancel a selection, in order to catch the
1563 mouse movement which is due to moving a window.
1565 For now the notification does not work In-Place.
1572 void SfxViewShell::OuterResizePixel
1574 const Point
& /*rToolOffset*/,// Upper left corner Tools in Frame-Window
1575 const Size
& /*rSize*/ // All available sizes.
1580 Override this Method to be able to react to the size-change of
1581 the View. Thus the View is defined as the Edit window and also the
1582 attached Tools are defined (for example the ruler).
1584 The Edit window must not be changed either in size or position.
1586 The Vis-Area of SfxObjectShell, its scale and position can be changed
1587 here. The main use is to change the size of the Vis-Area.
1589 If the Border is changed due to the new calculation then this has to be set
1590 by <SfxViewShell::SetBorderPixel(const SvBorder&)>. The Positioning of Tools
1591 is only allowed after the calling of 'SetBorderPixel'.
1595 void AppViewSh::OuterViewResizePixel( const Point &rOfs, const Size &rSz )
1597 // Calculate Tool position and size externally, do not set!
1598 // (due to the following Border calculation)
1599 Point aHLinPos...; Size aHLinSz...;
1602 // Calculate and Set a Border of Tools which matches rSize.
1604 SetBorderPixel( aBorder ); // Allow Positioning from here on.
1607 pHLin->SetPosSizePixel( aHLinPos, aHLinSz );
1613 <SfxViewShell::InnerResizePixel(const Point&,const Size& rSize)>
1617 SetBorderPixel( SvBorder() );
1621 void SfxViewShell::InnerResizePixel
1623 const Point
& /*rToolOffset*/,// Upper left corner Tools in Frame-Window
1624 const Size
& /*rSize*/, // All available sizes.
1630 Override this Method to be able to react to the size-change of
1633 The Edit window must not be changed either in size or position.
1634 Neither the Vis-Area of SfxObjectShell nor its scale or position are
1635 allowed to be changed
1637 If the Border is changed due to the new calculation then is has to be set
1638 by <SfxViewShell::SetBorderPixel(const SvBorder&)>.
1639 The Positioning of Tools is only allowed after the calling of
1645 void AppViewSh::InnerViewResizePixel( const Point &rOfs, const Size &rSz )
1647 // Calculate Tool position and size internally, do not set!
1648 // (due to the following Border calculation)
1649 Point aHLinPos...; Size aHLinSz...;
1652 // Calculate and Set a Border of Tools which matches rSize.
1654 SetBorderPixel( aBorder ); // Allow Positioning from here on.
1657 pHLin->SetPosSizePixel( aHLinPos, aHLinSz );
1663 <SfxViewShell::OuterResizePixel(const Point&,const Size& rSize)>
1667 SetBorderPixel( SvBorder() );
1670 void SfxViewShell::InvalidateBorder()
1672 GetViewFrame().InvalidateBorderImpl( this );
1673 if (pImpl
->m_pController
.is())
1675 pImpl
->m_pController
->BorderWidthsChanged_Impl();
1679 void SfxViewShell::SetBorderPixel( const SvBorder
&rBorder
)
1681 GetViewFrame().SetBorderPixelImpl( this, rBorder
);
1683 // notify related controller that border size is changed
1684 if (pImpl
->m_pController
.is())
1686 pImpl
->m_pController
->BorderWidthsChanged_Impl();
1690 const SvBorder
& SfxViewShell::GetBorderPixel() const
1692 return GetViewFrame().GetBorderPixelImpl();
1695 void SfxViewShell::SetWindow
1697 vcl::Window
* pViewPort
// For example Null pointer in the Destructor.
1702 With this method the SfxViewShell is set in the data window. This is
1703 needed for the in-place container and for restoring the proper focus.
1705 Even in-place-active the conversion of the ViewPort Windows is forbidden.
1709 if( pWindow
== pViewPort
)
1712 // Disconnect existing IP-Clients if possible
1713 DisconnectAllClients();
1716 bool bHadFocus
= pWindow
&& pWindow
->HasChildPathFocus( true );
1717 pWindow
= pViewPort
;
1721 // Disable automatic GUI mirroring (right-to-left) for document windows
1722 pWindow
->EnableRTL( false );
1725 if ( bHadFocus
&& pWindow
)
1726 pWindow
->GrabFocus();
1728 //Do we still need this Method?!
1729 //SfxGetpApp()->GrabFocus( pWindow );
1732 ViewShellDocId
SfxViewShell::mnCurrentDocId(0);
1734 SfxViewShell::SfxViewShell
1736 SfxViewFrame
& rViewFrame
, /* <SfxViewFrame>, which will be
1737 displayed in this View */
1738 SfxViewShellFlags nFlags
/* See <SfxViewShell-Flags> */
1742 , pImpl( new SfxViewShell_Impl(nFlags
, SfxViewShell::mnCurrentDocId
) )
1743 , rFrame(rViewFrame
)
1745 , bNoNewWindow( nFlags
& SfxViewShellFlags::NO_NEWWINDOW
)
1746 , mbPrinterSettingsModified(false)
1747 , maLOKLanguageTag(LANGUAGE_NONE
)
1748 , maLOKLocale(LANGUAGE_NONE
)
1749 , maLOKDeviceFormFactor(LOKDeviceFormFactor::UNKNOWN
)
1750 , mbLOKAccessibilityEnabled(false)
1752 SetMargin( rViewFrame
.GetMargin_Impl() );
1754 SetPool( &rViewFrame
.GetObjectShell()->GetPool() );
1755 StartListening(*rViewFrame
.GetObjectShell());
1758 std::vector
<SfxViewShell
*> &rViewArr
= SfxGetpApp()->GetViewShells_Impl();
1759 rViewArr
.push_back(this);
1761 if (comphelper::LibreOfficeKit::isActive())
1763 maLOKLanguageTag
= SfxLokHelper::getDefaultLanguage();
1764 maLOKLocale
= SfxLokHelper::getDefaultLanguage();
1766 const auto [isTimezoneSet
, aTimezone
] = SfxLokHelper::getDefaultTimezone();
1767 maLOKIsTimezoneSet
= isTimezoneSet
;
1768 maLOKTimezone
= aTimezone
;
1770 maLOKDeviceFormFactor
= SfxLokHelper::getDeviceFormFactor();
1772 vcl::Window
* pFrameWin
= rViewFrame
.GetWindow().GetFrameWindow();
1773 if (pFrameWin
&& !pFrameWin
->GetLOKNotifier())
1774 pFrameWin
->SetLOKNotifier(this, true);
1778 SfxViewShell::~SfxViewShell()
1781 const SfxViewShell
*pThis
= this;
1782 std::vector
<SfxViewShell
*> &rViewArr
= SfxGetpApp()->GetViewShells_Impl();
1783 auto it
= std::find( rViewArr
.begin(), rViewArr
.end(), pThis
);
1784 rViewArr
.erase( it
);
1786 if ( pImpl
->xClipboardListener
.is() )
1788 pImpl
->xClipboardListener
->DisconnectViewShell();
1789 pImpl
->xClipboardListener
= nullptr;
1792 if (pImpl
->m_pController
.is())
1794 pImpl
->m_pController
->ReleaseShell_Impl();
1795 pImpl
->m_pController
.clear();
1798 vcl::Window
* pFrameWin
= GetViewFrame().GetWindow().GetFrameWindow();
1799 if (pFrameWin
&& pFrameWin
->GetLOKNotifier() == this)
1800 pFrameWin
->ReleaseLOKNotifier();
1803 OUString
SfxViewShell::getA11yFocusedParagraph() const
1805 const LOKDocumentFocusListener
& rDocFocusListener
= GetLOKDocumentFocusListener();
1806 return rDocFocusListener
.getFocusedParagraph();
1809 int SfxViewShell::getA11yCaretPosition() const
1811 const LOKDocumentFocusListener
& rDocFocusListener
= GetLOKDocumentFocusListener();
1812 return rDocFocusListener
.getCaretPosition();
1815 bool SfxViewShell::PrepareClose
1817 bool bUI
// TRUE: Allow Dialog and so on, FALSE: silent-mode
1820 if (GetViewFrame().GetWindow().GetLOKNotifier() == this)
1821 GetViewFrame().GetWindow().ReleaseLOKNotifier();
1823 SfxPrinter
*pPrinter
= GetPrinter();
1824 if ( pPrinter
&& pPrinter
->IsPrinting() )
1828 std::unique_ptr
<weld::MessageDialog
> xBox(Application::CreateMessageDialog(GetViewFrame().GetFrameWeld(),
1829 VclMessageType::Info
, VclButtonsType::Ok
,
1830 SfxResId(STR_CANT_CLOSE
)));
1837 if( GetViewFrame().IsInModalMode() )
1840 if( bUI
&& GetViewFrame().GetDispatcher()->IsLocked() )
1847 SfxViewShell
* SfxViewShell::Current()
1849 SfxViewFrame
*pCurrent
= SfxViewFrame::Current();
1850 return pCurrent
? pCurrent
->GetViewShell() : nullptr;
1854 SfxViewShell
* SfxViewShell::Get( const Reference
< XController
>& i_rController
)
1856 if ( !i_rController
.is() )
1859 for ( SfxViewShell
* pViewShell
= SfxViewShell::GetFirst( false );
1861 pViewShell
= SfxViewShell::GetNext( *pViewShell
, false )
1864 if ( pViewShell
->GetController() == i_rController
)
1871 SdrView
* SfxViewShell::GetDrawView() const
1875 This virtual Method has to be overloaded by the sub classes, to be able
1876 make the Property-Editor available.
1878 The default implementation does always return zero.
1886 OUString
SfxViewShell::GetSelectionText
1888 bool /*bCompleteWords*/, /* FALSE (default)
1889 Only the actual selected text is returned.
1892 The selected text is expanded so that only
1893 whole words are returned. As word separators
1894 these are used: white spaces and punctuation
1895 ".,;" and single and double quotes.
1897 bool /*bOnlyASample*/ /* used by some dialogs to avoid constructing monster strings e.g. in calc */
1902 Override this Method to return a text that
1903 is included in the current selection. This is for example used when
1906 When called with "CompleteWords == TRUE", it is for example sufficient
1907 with having the Cursor positioned somewhere within a URL in-order
1908 to have the entire URL returned.
1916 bool SfxViewShell::HasSelection( bool ) const
1920 With this virtual Method can a for example a Dialog be queried, to
1921 check if something is selected in the current view. If the Parameter
1922 is <BOOL> TRUE then it is checked whether some text is selected.
1929 void SfxViewShell::AddSubShell( SfxShell
& rShell
)
1931 pImpl
->aArr
.push_back(&rShell
);
1932 SfxDispatcher
*pDisp
= rFrame
.GetDispatcher();
1933 if ( pDisp
->IsActive(*this) )
1935 pDisp
->Push(rShell
);
1940 void SfxViewShell::RemoveSubShell( SfxShell
* pShell
)
1942 SfxDispatcher
*pDisp
= rFrame
.GetDispatcher();
1945 size_t nCount
= pImpl
->aArr
.size();
1946 if ( pDisp
->IsActive(*this) )
1948 for(size_t n
= nCount
; n
> 0; --n
)
1949 pDisp
->Pop(*pImpl
->aArr
[n
- 1]);
1952 pImpl
->aArr
.clear();
1956 SfxShellArr_Impl::iterator i
= std::find(pImpl
->aArr
.begin(), pImpl
->aArr
.end(), pShell
);
1957 if(i
!= pImpl
->aArr
.end())
1959 pImpl
->aArr
.erase(i
);
1960 if(pDisp
->IsActive(*this))
1962 pDisp
->RemoveShell_Impl(*pShell
);
1969 SfxShell
* SfxViewShell::GetSubShell( sal_uInt16 nNo
)
1971 sal_uInt16 nCount
= pImpl
->aArr
.size();
1973 return pImpl
->aArr
[nCount
- nNo
- 1];
1977 void SfxViewShell::PushSubShells_Impl( bool bPush
)
1979 SfxDispatcher
*pDisp
= rFrame
.GetDispatcher();
1982 for (auto const& elem
: pImpl
->aArr
)
1985 else if(!pImpl
->aArr
.empty())
1987 SfxShell
& rPopUntil
= *pImpl
->aArr
[0];
1988 if ( pDisp
->GetShellLevel( rPopUntil
) != USHRT_MAX
)
1989 pDisp
->Pop( rPopUntil
, SfxDispatcherPopFlags::POP_UNTIL
);
1996 void SfxViewShell::WriteUserData( OUString
&, bool )
2001 void SfxViewShell::ReadUserData(const OUString
&, bool )
2005 void SfxViewShell::ReadUserDataSequence ( const uno::Sequence
< beans::PropertyValue
>& )
2009 void SfxViewShell::WriteUserDataSequence ( uno::Sequence
< beans::PropertyValue
>& )
2014 // returns the first shell of spec. type viewing the specified doc.
2015 SfxViewShell
* SfxViewShell::GetFirst
2018 const std::function
< bool ( const SfxViewShell
* ) >& isViewShell
2021 // search for a SfxViewShell of the specified type
2022 std::vector
<SfxViewShell
*> &rShells
= SfxGetpApp()->GetViewShells_Impl();
2023 for (SfxViewShell
* pShell
: rShells
)
2027 // This code used to check that the frame exists in the other list,
2028 // because of https://bz.apache.org/ooo/show_bug.cgi?id=62084, with the explanation:
2029 // sometimes dangling SfxViewShells exist that point to a dead SfxViewFrame
2030 // these ViewShells shouldn't be accessible anymore
2031 // a destroyed ViewFrame is not in the ViewFrame array anymore, so checking this array helps
2032 // That doesn't seem to be needed anymore, but keep an assert, just in case.
2033 assert(std::find(SfxGetpApp()->GetViewFrames_Impl().begin(), SfxGetpApp()->GetViewFrames_Impl().end(),
2034 &pShell
->GetViewFrame()) != SfxGetpApp()->GetViewFrames_Impl().end());
2035 if ( ( !bOnlyVisible
|| pShell
->GetViewFrame().IsVisible() ) && (!isViewShell
|| isViewShell(pShell
)))
2043 // returns the next shell of spec. type viewing the specified doc.
2044 SfxViewShell
* SfxViewShell::GetNext
2046 const SfxViewShell
& rPrev
,
2048 const std::function
<bool ( const SfxViewShell
* )>& isViewShell
2051 std::vector
<SfxViewShell
*> &rShells
= SfxGetpApp()->GetViewShells_Impl();
2053 for ( nPos
= 0; nPos
< rShells
.size(); ++nPos
)
2054 if ( rShells
[nPos
] == &rPrev
)
2057 for ( ++nPos
; nPos
< rShells
.size(); ++nPos
)
2059 SfxViewShell
*pShell
= rShells
[nPos
];
2062 assert(std::find(SfxGetpApp()->GetViewFrames_Impl().begin(), SfxGetpApp()->GetViewFrames_Impl().end(),
2063 &pShell
->GetViewFrame()) != SfxGetpApp()->GetViewFrames_Impl().end());
2064 if ( ( !bOnlyVisible
|| pShell
->GetViewFrame().IsVisible() ) && (!isViewShell
|| isViewShell(pShell
)) )
2073 void SfxViewShell::Notify( SfxBroadcaster
& rBC
,
2074 const SfxHint
& rHint
)
2076 const SfxEventHint
* pEventHint
= dynamic_cast<const SfxEventHint
*>(&rHint
);
2077 if ( !(pEventHint
&& pEventHint
->GetEventId() == SfxEventHintId::LoadFinished
) )
2080 if ( !GetController().is() )
2083 // avoid access to dangling ViewShells
2084 auto &rFrames
= SfxGetpApp()->GetViewFrames_Impl();
2085 for (SfxViewFrame
* frame
: rFrames
)
2087 if ( frame
== &GetViewFrame() && &rBC
== GetObjectShell() )
2089 SfxItemSet
* pSet
= GetObjectShell()->GetMedium()->GetItemSet();
2090 const SfxUnoAnyItem
* pItem
= SfxItemSet::GetItem
<SfxUnoAnyItem
>(pSet
, SID_VIEW_DATA
, false);
2093 pImpl
->m_pController
->restoreViewData( pItem
->GetValue() );
2094 pSet
->ClearItem( SID_VIEW_DATA
);
2101 bool SfxViewShell::ExecKey_Impl(const KeyEvent
& aKey
)
2103 bool setModuleConfig
= false; // In case libreofficekit is active, we will re-set the module config class.
2104 if (!pImpl
->m_xAccExec
)
2106 pImpl
->m_xAccExec
= ::svt::AcceleratorExecute::createAcceleratorHelper();
2107 pImpl
->m_xAccExec
->init(::comphelper::getProcessComponentContext(),
2108 rFrame
.GetFrame().GetFrameInterface());
2109 setModuleConfig
= true;
2112 if (comphelper::LibreOfficeKit::isActive())
2114 // Get the module name.
2115 css::uno::Reference
< css::uno::XComponentContext
> xContext (::comphelper::getProcessComponentContext());
2116 css::uno::Reference
< css::frame::XModuleManager2
> xModuleManager(css::frame::ModuleManager::create(xContext
));
2117 OUString sModule
= xModuleManager
->identify(rFrame
.GetFrame().GetFrameInterface());
2119 // Get the language name.
2120 OUString viewLang
= GetLOKLanguageTag().getBcp47();
2122 // Merge them & have a key.
2123 OUString key
= sModule
+ viewLang
;
2125 // Check it in configurations map. Create a configuration manager if there isn't one for the key.
2126 std::unordered_map
<OUString
, css::uno::Reference
<com::sun::star::ui::XAcceleratorConfiguration
>>& acceleratorConfs
= SfxApplication::Get()->GetAcceleratorConfs_Impl();
2127 if (acceleratorConfs
.find(key
) == acceleratorConfs
.end())
2129 // Create a new configuration manager for the module.
2131 OUString actualLang
= officecfg::Setup::L10N::ooLocale::get();
2133 std::shared_ptr
<comphelper::ConfigurationChanges
> batch(comphelper::ConfigurationChanges::create());
2134 officecfg::Setup::L10N::ooLocale::set(viewLang
, batch
);
2137 // We have set the language. Time to create the config manager.
2138 acceleratorConfs
[key
] = svt::AcceleratorExecute::lok_createNewAcceleratorConfiguration(::comphelper::getProcessComponentContext(), sModule
);
2140 std::shared_ptr
<comphelper::ConfigurationChanges
> batch2(comphelper::ConfigurationChanges::create());
2141 officecfg::Setup::L10N::ooLocale::set(actualLang
, batch2
);
2145 if (setModuleConfig
)
2146 pImpl
->m_xAccExec
->lok_setModuleConfig(acceleratorConfs
[key
]);
2149 return pImpl
->m_xAccExec
->execute(aKey
.GetKeyCode());
2152 void SfxViewShell::setLibreOfficeKitViewCallback(SfxLokCallbackInterface
* pCallback
)
2154 pImpl
->m_pLibreOfficeKitViewCallback
= pCallback
;
2156 afterCallbackRegistered();
2158 if (!pImpl
->m_pLibreOfficeKitViewCallback
)
2161 // Ask other views to tell us about their cursors.
2162 SfxViewShell
* pViewShell
= SfxViewShell::GetFirst();
2165 if (pViewShell
->GetDocId() == GetDocId())
2166 pViewShell
->NotifyCursor(this);
2167 pViewShell
= SfxViewShell::GetNext(*pViewShell
);
2171 SfxLokCallbackInterface
* SfxViewShell::getLibreOfficeKitViewCallback() const
2173 return pImpl
->m_pLibreOfficeKitViewCallback
;
2176 void SfxViewShell::dumpLibreOfficeKitViewState(rtl::OStringBuffer
&rState
)
2178 if (pImpl
->m_pLibreOfficeKitViewCallback
)
2179 pImpl
->m_pLibreOfficeKitViewCallback
->dumpState(rState
);
2182 static bool ignoreLibreOfficeKitViewCallback(int nType
, const SfxViewShell_Impl
* pImpl
)
2184 if (!comphelper::LibreOfficeKit::isActive())
2187 if (comphelper::LibreOfficeKit::isTiledPainting())
2191 case LOK_CALLBACK_FORM_FIELD_BUTTON
:
2192 case LOK_CALLBACK_TEXT_SELECTION
:
2193 case LOK_CALLBACK_COMMENT
:
2196 // Reject e.g. invalidate during paint.
2201 if (pImpl
->m_bTiledSearching
)
2205 case LOK_CALLBACK_TEXT_SELECTION
:
2206 case LOK_CALLBACK_TEXT_VIEW_SELECTION
:
2207 case LOK_CALLBACK_TEXT_SELECTION_START
:
2208 case LOK_CALLBACK_TEXT_SELECTION_END
:
2209 case LOK_CALLBACK_GRAPHIC_SELECTION
:
2210 case LOK_CALLBACK_GRAPHIC_VIEW_SELECTION
:
2218 void SfxViewShell::libreOfficeKitViewInvalidateTilesCallback(const tools::Rectangle
* pRect
, int nPart
, int nMode
) const
2220 if (ignoreLibreOfficeKitViewCallback(LOK_CALLBACK_INVALIDATE_TILES
, pImpl
.get()))
2222 if (pImpl
->m_pLibreOfficeKitViewCallback
)
2223 pImpl
->m_pLibreOfficeKitViewCallback
->libreOfficeKitViewInvalidateTilesCallback(pRect
, nPart
, nMode
);
2227 "SfxViewShell::libreOfficeKitViewInvalidateTilesCallback no callback set!");
2230 void SfxViewShell::libreOfficeKitViewCallbackWithViewId(int nType
, const OString
& pPayload
, int nViewId
) const
2232 if (ignoreLibreOfficeKitViewCallback(nType
, pImpl
.get()))
2234 if (pImpl
->m_pLibreOfficeKitViewCallback
)
2235 pImpl
->m_pLibreOfficeKitViewCallback
->libreOfficeKitViewCallbackWithViewId(nType
, pPayload
, nViewId
);
2239 "SfxViewShell::libreOfficeKitViewCallbackWithViewId no callback set! Dropped payload of type "
2240 << lokCallbackTypeToString(nType
) << ": [" << pPayload
<< ']');
2243 void SfxViewShell::libreOfficeKitViewCallback(int nType
, const OString
& pPayload
) const
2245 if (ignoreLibreOfficeKitViewCallback(nType
, pImpl
.get()))
2247 if (pImpl
->m_pLibreOfficeKitViewCallback
)
2248 pImpl
->m_pLibreOfficeKitViewCallback
->libreOfficeKitViewCallback(nType
, pPayload
);
2252 "SfxViewShell::libreOfficeKitViewCallback no callback set! Dropped payload of type "
2253 << lokCallbackTypeToString(nType
) << ": [" << pPayload
<< ']');
2256 void SfxViewShell::libreOfficeKitViewUpdatedCallback(int nType
) const
2258 if (ignoreLibreOfficeKitViewCallback(nType
, pImpl
.get()))
2260 if (pImpl
->m_pLibreOfficeKitViewCallback
)
2261 pImpl
->m_pLibreOfficeKitViewCallback
->libreOfficeKitViewUpdatedCallback(nType
);
2265 "SfxViewShell::libreOfficeKitViewUpdatedCallback no callback set! Dropped payload of type "
2266 << lokCallbackTypeToString(nType
));
2269 void SfxViewShell::libreOfficeKitViewUpdatedCallbackPerViewId(int nType
, int nViewId
, int nSourceViewId
) const
2271 if (ignoreLibreOfficeKitViewCallback(nType
, pImpl
.get()))
2273 if (pImpl
->m_pLibreOfficeKitViewCallback
)
2274 pImpl
->m_pLibreOfficeKitViewCallback
->libreOfficeKitViewUpdatedCallbackPerViewId(nType
, nViewId
, nSourceViewId
);
2278 "SfxViewShell::libreOfficeKitViewUpdatedCallbackPerViewId no callback set! Dropped payload of type "
2279 << lokCallbackTypeToString(nType
));
2282 void SfxViewShell::libreOfficeKitViewAddPendingInvalidateTiles()
2284 if (pImpl
->m_pLibreOfficeKitViewCallback
)
2285 pImpl
->m_pLibreOfficeKitViewCallback
->libreOfficeKitViewAddPendingInvalidateTiles();
2289 "SfxViewShell::libreOfficeKitViewAddPendingInvalidateTiles no callback set!");
2292 void SfxViewShell::afterCallbackRegistered()
2296 void SfxViewShell::flushPendingLOKInvalidateTiles()
2298 // SfxViewShell itself does not delay any tile invalidations.
2301 std::optional
<OString
> SfxViewShell::getLOKPayload(int nType
, int /*nViewId*/) const
2303 // SfxViewShell itself currently doesn't handle any updated-payload types.
2304 SAL_WARN("sfx.view", "SfxViewShell::getLOKPayload unhandled type " << lokCallbackTypeToString(nType
));
2308 vcl::Window
* SfxViewShell::GetEditWindowForActiveOLEObj() const
2310 vcl::Window
* pEditWin
= nullptr;
2311 SfxInPlaceClient
* pIPClient
= GetIPClient();
2314 pEditWin
= pIPClient
->GetEditWin();
2319 void SfxViewShell::SetLOKLanguageTag(const OUString
& rBcp47LanguageTag
)
2321 LanguageTag
aTag(rBcp47LanguageTag
, true);
2323 css::uno::Sequence
<OUString
> inst(officecfg::Setup::Office::InstalledLocales::get()->getElementNames());
2324 LanguageTag aFallbackTag
= LanguageTag(getInstalledLocaleForSystemUILanguage(inst
, /* bRequestInstallIfMissing */ false, rBcp47LanguageTag
), true).makeFallback();
2326 // If we want de-CH, and the de localisation is available, we don't want to use de-DE as then
2327 // the magic in Translate::get() won't turn ess-zet into double s. Possibly other similar cases?
2328 if (comphelper::LibreOfficeKit::isActive() && aTag
.getLanguage() == aFallbackTag
.getLanguage())
2329 maLOKLanguageTag
= aTag
;
2331 maLOKLanguageTag
= aFallbackTag
;
2334 LOKDocumentFocusListener
& SfxViewShell::GetLOKDocumentFocusListener()
2336 if (mpLOKDocumentFocusListener
)
2337 return *mpLOKDocumentFocusListener
;
2339 mpLOKDocumentFocusListener
= new LOKDocumentFocusListener(this);
2340 return *mpLOKDocumentFocusListener
;
2343 const LOKDocumentFocusListener
& SfxViewShell::GetLOKDocumentFocusListener() const
2345 return const_cast<SfxViewShell
*>(this)->GetLOKDocumentFocusListener();
2348 void SfxViewShell::SetLOKAccessibilityState(bool bEnabled
)
2350 if (bEnabled
== mbLOKAccessibilityEnabled
)
2352 mbLOKAccessibilityEnabled
= bEnabled
;
2354 LOKDocumentFocusListener
& rDocumentFocusListener
= GetLOKDocumentFocusListener();
2359 uno::Reference
< accessibility::XAccessible
> xAccessible
=
2360 pWindow
->GetAccessible();
2362 if (!xAccessible
.is())
2365 if (mbLOKAccessibilityEnabled
)
2369 rDocumentFocusListener
.attachRecursive(xAccessible
);
2371 catch (const uno::Exception
&)
2373 SAL_WARN("lok.a11y", "Exception caught processing LOKDocumentFocusListener::attachRecursive");
2380 rDocumentFocusListener
.detachRecursive(xAccessible
);
2382 catch (const uno::Exception
&)
2384 SAL_WARN("lok.a11y", "Exception caught processing LOKDocumentFocusListener::detachRecursive");
2389 void SfxViewShell::SetLOKLocale(const OUString
& rBcp47LanguageTag
)
2391 maLOKLocale
= LanguageTag(rBcp47LanguageTag
, true).makeFallback();
2394 void SfxViewShell::NotifyCursor(SfxViewShell
* /*pViewShell*/) const
2398 void SfxViewShell::setTiledSearching(bool bTiledSearching
)
2400 pImpl
->m_bTiledSearching
= bTiledSearching
;
2403 int SfxViewShell::getPart() const
2408 int SfxViewShell::getEditMode() const
2413 ViewShellId
SfxViewShell::GetViewShellId() const
2415 return pImpl
->m_nViewShellId
;
2418 void SfxViewShell::SetCurrentDocId(ViewShellDocId nId
)
2420 mnCurrentDocId
= nId
;
2423 ViewShellDocId
SfxViewShell::GetDocId() const
2425 assert(pImpl
->m_nDocId
>= ViewShellDocId(0) && "m_nDocId should have been initialized, but it is invalid.");
2426 return pImpl
->m_nDocId
;
2429 void SfxViewShell::notifyInvalidation(tools::Rectangle
const* pRect
) const
2431 SfxLokHelper::notifyInvalidation(this, pRect
);
2434 void SfxViewShell::NotifyOtherViews(int nType
, const OString
& rKey
, const OString
& rPayload
)
2436 SfxLokHelper::notifyOtherViews(this, nType
, rKey
, rPayload
);
2439 void SfxViewShell::NotifyOtherView(OutlinerViewShell
* pOther
, int nType
, const OString
& rKey
, const OString
& rPayload
)
2441 auto pOtherShell
= dynamic_cast<SfxViewShell
*>(pOther
);
2445 SfxLokHelper::notifyOtherView(this, pOtherShell
, nType
, rKey
, rPayload
);
2448 void SfxViewShell::dumpAsXml(xmlTextWriterPtr pWriter
) const
2450 (void)xmlTextWriterStartElement(pWriter
, BAD_CAST("SfxViewShell"));
2451 (void)xmlTextWriterWriteFormatAttribute(pWriter
, BAD_CAST("ptr"), "%p", this);
2452 (void)xmlTextWriterWriteAttribute(pWriter
, BAD_CAST("id"), BAD_CAST(OString::number(static_cast<sal_Int32
>(GetViewShellId())).getStr()));
2453 (void)xmlTextWriterEndElement(pWriter
);
2456 bool SfxViewShell::KeyInput( const KeyEvent
&rKeyEvent
)
2460 This Method executes the KeyEvent 'rKeyEvent' of the Keys (Accelerator)
2461 configured either direct or indirect (for example by the Application)
2462 in the SfxViewShell.
2467 The Key (Accelerator) is configured and the
2468 associated Handler was called
2471 The Key (Accelerator) is not configured and
2472 subsequently no Handler was called
2476 <SfxApplication::KeyInput(const KeyEvent&)>
2479 return ExecKey_Impl(rKeyEvent
);
2482 bool SfxViewShell::GlobalKeyInput_Impl( const KeyEvent
&rKeyEvent
)
2484 return ExecKey_Impl(rKeyEvent
);
2488 void SfxViewShell::ShowCursor( bool /*bOn*/ )
2492 Subclasses must override this Method so that SFx can switch the
2493 Cursor on and off, for example while a <SfxProgress> is running.
2500 void SfxViewShell::ResetAllClients_Impl( SfxInPlaceClient
const *pIP
)
2503 std::vector
< SfxInPlaceClient
* >& rClients
= pImpl
->GetIPClients_Impl();
2504 if ( rClients
.empty() )
2507 for (SfxInPlaceClient
* pIPClient
: rClients
)
2509 if( pIPClient
!= pIP
)
2510 pIPClient
->ResetObject();
2515 void SfxViewShell::DisconnectAllClients()
2517 std::vector
< SfxInPlaceClient
* >& rClients
= pImpl
->GetIPClients_Impl();
2518 if ( rClients
.empty() )
2521 for ( size_t n
= 0; n
< rClients
.size(); )
2522 // clients will remove themselves from the list
2523 delete rClients
.at( n
);
2527 void SfxViewShell::QueryObjAreaPixel( tools::Rectangle
& ) const
2532 void SfxViewShell::VisAreaChanged()
2534 std::vector
< SfxInPlaceClient
* >& rClients
= pImpl
->GetIPClients_Impl();
2535 if ( rClients
.empty() )
2538 for (SfxInPlaceClient
* pIPClient
: rClients
)
2540 if ( pIPClient
->IsObjectInPlaceActive() )
2541 // client is active, notify client that the VisArea might have changed
2542 pIPClient
->VisAreaChanged();
2547 void SfxViewShell::CheckIPClient_Impl(
2548 SfxInPlaceClient
const *const pIPClient
, const tools::Rectangle
& rVisArea
)
2550 if ( GetObjectShell()->IsInClose() )
2553 bool bAlwaysActive
=
2554 ( ( pIPClient
->GetObjectMiscStatus() & embed::EmbedMisc::EMBED_ACTIVATEIMMEDIATELY
) != 0 );
2555 bool bActiveWhenVisible
=
2556 ( pIPClient
->GetObjectMiscStatus() & embed::EmbedMisc::MS_EMBED_ACTIVATEWHENVISIBLE
) != 0;
2558 // this method is called when a client is created
2559 if (pIPClient
->IsObjectInPlaceActive())
2562 // object in client is currently not active
2563 // check if the object wants to be activated always or when it becomes at least partially visible
2564 // TODO/LATER: maybe we should use the scaled area instead of the ObjArea?!
2565 if (bAlwaysActive
|| (bActiveWhenVisible
&& rVisArea
.Overlaps(pIPClient
->GetObjArea())))
2569 pIPClient
->GetObject()->changeState( embed::EmbedStates::INPLACE_ACTIVE
);
2571 catch (const uno::Exception
&)
2573 TOOLS_WARN_EXCEPTION("sfx.view", "SfxViewShell::CheckIPClient_Impl");
2578 SfxObjectShell
* SfxViewShell::GetObjectShell()
2580 return rFrame
.GetObjectShell();
2583 Reference
< XModel
> SfxViewShell::GetCurrentDocument() const
2585 Reference
< XModel
> xDocument
;
2587 const SfxObjectShell
* pDocShell( const_cast< SfxViewShell
* >( this )->GetObjectShell() );
2588 OSL_ENSURE( pDocShell
, "SfxViewFrame::GetCurrentDocument: no DocShell!?" );
2590 xDocument
= pDocShell
->GetModel();
2595 void SfxViewShell::SetCurrentDocument() const
2597 uno::Reference
< frame::XModel
> xDocument( GetCurrentDocument() );
2598 if ( xDocument
.is() )
2599 SfxObjectShell::SetCurrentComponent( xDocument
);
2603 const Size
& SfxViewShell::GetMargin() const
2605 return pImpl
->aMargin
;
2609 void SfxViewShell::SetMargin( const Size
& rSize
)
2611 // the default margin was verified using www.apple.com !!
2612 Size aMargin
= rSize
;
2613 if ( aMargin
.Width() == -1 )
2614 aMargin
.setWidth( DEFAULT_MARGIN_WIDTH
);
2615 if ( aMargin
.Height() == -1 )
2616 aMargin
.setHeight( DEFAULT_MARGIN_HEIGHT
);
2618 if ( aMargin
!= pImpl
->aMargin
)
2620 pImpl
->aMargin
= aMargin
;
2625 void SfxViewShell::MarginChanged()
2629 void SfxViewShell::JumpToMark( const OUString
& rMark
)
2631 SfxStringItem
aMarkItem( SID_JUMPTOMARK
, rMark
);
2632 GetViewFrame().GetDispatcher()->ExecuteList(
2634 SfxCallMode::SYNCHRON
|SfxCallMode::RECORD
,
2638 void SfxViewShell::SetController( SfxBaseController
* pController
)
2640 pImpl
->m_pController
= pController
;
2642 // there should be no old listener, but if there is one, it should be disconnected
2643 if ( pImpl
->xClipboardListener
.is() )
2644 pImpl
->xClipboardListener
->DisconnectViewShell();
2646 pImpl
->xClipboardListener
= new SfxClipboardChangeListener( this, GetClipboardNotifier() );
2649 Reference
< XController
> SfxViewShell::GetController() const
2651 return pImpl
->m_pController
;
2654 SfxBaseController
* SfxViewShell::GetBaseController_Impl() const
2656 return pImpl
->m_pController
.get();
2659 void SfxViewShell::AddContextMenuInterceptor_Impl( const uno::Reference
< ui::XContextMenuInterceptor
>& xInterceptor
)
2661 std::unique_lock
g(pImpl
->aMutex
);
2662 pImpl
->aInterceptorContainer
.addInterface( g
, xInterceptor
);
2665 void SfxViewShell::RemoveContextMenuInterceptor_Impl( const uno::Reference
< ui::XContextMenuInterceptor
>& xInterceptor
)
2667 std::unique_lock
g(pImpl
->aMutex
);
2668 pImpl
->aInterceptorContainer
.removeInterface( g
, xInterceptor
);
2671 bool SfxViewShell::TryContextMenuInterception(const rtl::Reference
<VCLXPopupMenu
>& rIn
,
2672 const OUString
& rMenuIdentifier
,
2673 rtl::Reference
<VCLXPopupMenu
>& rOut
,
2674 ui::ContextMenuExecuteEvent aEvent
)
2677 bool bModified
= false;
2679 // create container from menu
2680 aEvent
.ActionTriggerContainer
= ::framework::ActionTriggerHelper::CreateActionTriggerContainerFromMenu(
2681 rIn
, &rMenuIdentifier
);
2683 // get selection from controller
2684 aEvent
.Selection
.set( GetController(), uno::UNO_QUERY
);
2686 // call interceptors
2687 std::unique_lock
g(pImpl
->aMutex
);
2688 std::vector
<uno::Reference
< ui::XContextMenuInterceptor
>> aInterceptors
=
2689 pImpl
->aInterceptorContainer
.getElements(g
);
2691 for (const auto & rListener
: aInterceptors
)
2695 ui::ContextMenuInterceptorAction eAction
;
2697 SolarMutexReleaser rel
;
2698 eAction
= rListener
->notifyContextMenuExecute( aEvent
);
2702 case ui::ContextMenuInterceptorAction_CANCELLED
:
2703 // interceptor does not want execution
2705 case ui::ContextMenuInterceptorAction_EXECUTE_MODIFIED
:
2706 // interceptor wants his modified menu to be executed
2709 case ui::ContextMenuInterceptorAction_CONTINUE_MODIFIED
:
2710 // interceptor has modified menu, but allows for calling other interceptors
2713 case ui::ContextMenuInterceptorAction_IGNORED
:
2714 // interceptor is indifferent
2717 OSL_FAIL("Wrong return value of ContextMenuInterceptor!");
2724 pImpl
->aInterceptorContainer
.removeInterface(g
, rListener
);
2733 // container was modified, create a new menu out of it
2734 rOut
= new VCLXPopupMenu();
2735 ::framework::ActionTriggerHelper::CreateMenuFromActionTriggerContainer(rOut
, aEvent
.ActionTriggerContainer
);
2741 bool SfxViewShell::TryContextMenuInterception(const rtl::Reference
<VCLXPopupMenu
>& rPopupMenu
,
2742 const OUString
& rMenuIdentifier
, css::ui::ContextMenuExecuteEvent aEvent
)
2744 bool bModified
= false;
2746 // create container from menu
2747 aEvent
.ActionTriggerContainer
= ::framework::ActionTriggerHelper::CreateActionTriggerContainerFromMenu(
2748 rPopupMenu
, &rMenuIdentifier
);
2750 // get selection from controller
2751 aEvent
.Selection
= css::uno::Reference
< css::view::XSelectionSupplier
>( GetController(), css::uno::UNO_QUERY
);
2753 // call interceptors
2754 std::unique_lock
g(pImpl
->aMutex
);
2755 std::vector
<uno::Reference
< ui::XContextMenuInterceptor
>> aInterceptors
=
2756 pImpl
->aInterceptorContainer
.getElements(g
);
2758 for (const auto & rListener
: aInterceptors
)
2762 css::ui::ContextMenuInterceptorAction eAction
;
2764 SolarMutexReleaser rel
;
2765 eAction
= rListener
->notifyContextMenuExecute( aEvent
);
2769 case css::ui::ContextMenuInterceptorAction_CANCELLED
:
2770 // interceptor does not want execution
2772 case css::ui::ContextMenuInterceptorAction_EXECUTE_MODIFIED
:
2773 // interceptor wants his modified menu to be executed
2776 case css::ui::ContextMenuInterceptorAction_CONTINUE_MODIFIED
:
2777 // interceptor has modified menu, but allows for calling other interceptors
2780 case css::ui::ContextMenuInterceptorAction_IGNORED
:
2781 // interceptor is indifferent
2784 SAL_WARN( "sfx.view", "Wrong return value of ContextMenuInterceptor!" );
2791 pImpl
->aInterceptorContainer
.removeInterface(g
, rListener
);
2800 rPopupMenu
->clear();
2801 ::framework::ActionTriggerHelper::CreateMenuFromActionTriggerContainer(rPopupMenu
, aEvent
.ActionTriggerContainer
);
2807 bool SfxViewShell::HandleNotifyEvent_Impl( NotifyEvent
const & rEvent
)
2809 if (pImpl
->m_pController
.is())
2810 return pImpl
->m_pController
->HandleEvent_Impl( rEvent
);
2814 bool SfxViewShell::HasKeyListeners_Impl() const
2816 return (pImpl
->m_pController
.is())
2817 && pImpl
->m_pController
->HasKeyListeners_Impl();
2820 bool SfxViewShell::HasMouseClickListeners_Impl() const
2822 return (pImpl
->m_pController
.is())
2823 && pImpl
->m_pController
->HasMouseClickListeners_Impl();
2826 bool SfxViewShell::Escape()
2828 return GetViewFrame().GetBindings().Execute(SID_TERMINATE_INPLACEACTIVATION
);
2831 Reference
< view::XRenderable
> SfxViewShell::GetRenderable()
2833 Reference
< view::XRenderable
>xRender
;
2834 SfxObjectShell
* pObj
= GetObjectShell();
2837 Reference
< frame::XModel
> xModel( pObj
->GetModel() );
2839 xRender
.set( xModel
, UNO_QUERY
);
2844 void SfxViewShell::notifyWindow(vcl::LOKWindowId nDialogId
, const OUString
& rAction
, const std::vector
<vcl::LOKPayloadItem
>& rPayload
) const
2846 SfxLokHelper::notifyWindow(this, nDialogId
, rAction
, rPayload
);
2849 uno::Reference
< datatransfer::clipboard::XClipboardNotifier
> SfxViewShell::GetClipboardNotifier() const
2851 uno::Reference
< datatransfer::clipboard::XClipboardNotifier
> xClipboardNotifier
;
2852 xClipboardNotifier
.set(GetViewFrame().GetWindow().GetClipboard(), uno::UNO_QUERY
);
2853 return xClipboardNotifier
;
2856 void SfxViewShell::AddRemoveClipboardListener( const uno::Reference
< datatransfer::clipboard::XClipboardListener
>& rClp
, bool bAdd
)
2860 uno::Reference
< datatransfer::clipboard::XClipboard
> xClipboard(GetViewFrame().GetWindow().GetClipboard());
2861 if( xClipboard
.is() )
2863 uno::Reference
< datatransfer::clipboard::XClipboardNotifier
> xClpbrdNtfr( xClipboard
, uno::UNO_QUERY
);
2864 if( xClpbrdNtfr
.is() )
2867 xClpbrdNtfr
->addClipboardListener( rClp
);
2869 xClpbrdNtfr
->removeClipboardListener( rClp
);
2873 catch (const uno::Exception
&)
2878 weld::Window
* SfxViewShell::GetFrameWeld() const
2880 return pWindow
? pWindow
->GetFrameWeld() : nullptr;
2883 void SfxViewShell::setBlockedCommandList(const char* blockedCommandList
)
2885 if(!mvLOKBlockedCommandList
.empty())
2888 OUString
BlockedListString(blockedCommandList
, strlen(blockedCommandList
), RTL_TEXTENCODING_UTF8
);
2889 OUString command
= BlockedListString
.getToken(0, ' ');
2890 for (size_t i
= 1; !command
.isEmpty(); i
++)
2892 mvLOKBlockedCommandList
.emplace(command
);
2893 command
= BlockedListString
.getToken(i
, ' ');
2897 bool SfxViewShell::isBlockedCommand(OUString command
)
2899 return mvLOKBlockedCommandList
.find(command
) != mvLOKBlockedCommandList
.end();
2902 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */