1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
19 #ifndef INCLUDED_SFX2_VIEWSH_HXX
20 #define INCLUDED_SFX2_VIEWSH_HXX
22 #include <sal/config.h>
25 #include <sfx2/dllapi.h>
26 #include <sal/types.h>
27 #include <com/sun/star/uno/Reference.h>
28 #include <svl/lstner.hxx>
29 #include <sfx2/shell.hxx>
30 #include <i18nlangtag/languagetag.hxx>
31 #include <vcl/IDialogRenderable.hxx>
32 #include <comphelper/errcode.hxx>
33 #include <o3tl/typed_flags_set.hxx>
34 #include <vcl/vclptr.hxx>
35 #include <editeng/outliner.hxx>
37 #include <unordered_set>
38 #include <unordered_map>
41 class SfxBaseController
;
47 class DialogController
;
58 class SfxInPlaceClient
;
59 class SfxLokCallbackInterface
;
60 class LOKDocumentFocusListener
;
61 class SfxStoringHelper
;
63 namespace rtl
{ class OStringBuffer
; }
64 namespace vcl
{ class PrinterController
; }
66 namespace com::sun::star::awt
{ class XPopupMenu
; }
67 namespace com::sun::star::beans
{ struct PropertyValue
; }
68 namespace com::sun::star::datatransfer::clipboard
{ class XClipboardListener
; }
69 namespace com::sun::star::datatransfer::clipboard
{ class XClipboardNotifier
; }
70 namespace com::sun::star::embed
{ class XEmbeddedObject
; }
71 namespace com::sun::star::frame
{ class XController
; }
72 namespace com::sun::star::frame
{ class XModel
; }
73 namespace com::sun::star::ui
{ class XContextMenuInterceptor
; }
74 namespace com::sun::star::ui
{ struct ContextMenuExecuteEvent
; }
75 namespace com::sun::star::view
{ class XRenderable
; }
76 namespace tools
{ class Rectangle
; }
78 enum class SfxPrinterChangeFlags
81 PRINTER
= 1, // without JOB SETUP => Temporary
89 template<> struct typed_flags
<SfxPrinterChangeFlags
> : is_typed_flags
<SfxPrinterChangeFlags
, 31> {};
91 #define SFX_PRINTER_ALL (SfxPrinterChangeFlags::PRINTER | SfxPrinterChangeFlags::JOBSETUP | SfxPrinterChangeFlags::OPTIONS | SfxPrinterChangeFlags::CHG_ORIENTATION | SfxPrinterChangeFlags::CHG_SIZE)
93 #define SFX_PRINTERROR_BUSY 1
95 // "Verified" using www.apple.com and Netscape 3.01
96 #define DEFAULT_MARGIN_WIDTH 8
97 #define DEFAULT_MARGIN_HEIGHT 12
100 // @[SfxViewShell-Flags]
102 enum class SfxViewShellFlags
105 HAS_PRINTOPTIONS
= 0x0010, /* Options-Button and Options-Dialog in PrintDialog */
106 NO_NEWWINDOW
= 0x0100, /* Allow N View */
110 template<> struct typed_flags
<SfxViewShellFlags
> : is_typed_flags
<SfxViewShellFlags
, 0x0110> {};
115 The SfxViewShell flags control the behavior of SfxViewShell for the
116 duration of its lifetime. They are defined in the constructor of
120 enum class LOKDeviceFormFactor
128 class SfxViewFactory
;
129 #define SFX_DECL_VIEWFACTORY(Class) \
131 static SfxViewFactory *s_pFactory; \
133 static SfxViewShell *CreateInstance(SfxViewFrame& rFrame, SfxViewShell *pOldView); \
134 static void RegisterFactory( SfxInterfaceId nPrio ); \
135 static SfxViewFactory*Factory() { return s_pFactory; } \
136 static void InitFactory()
138 #define SFX_IMPL_NAMED_VIEWFACTORY(Class, AsciiViewName) \
139 SfxViewFactory* Class::s_pFactory; \
140 SfxViewShell* Class::CreateInstance(SfxViewFrame& rFrame, SfxViewShell *pOldView) \
141 { return new Class(rFrame, pOldView); } \
142 void Class::RegisterFactory( SfxInterfaceId nPrio ) \
144 s_pFactory = new SfxViewFactory(&CreateInstance,nPrio,AsciiViewName);\
147 void Class::InitFactory()
149 #define SFX_VIEW_REGISTRATION(DocClass) \
150 DocClass::Factory().RegisterViewFactory( *Factory() )
152 template<class T
> bool checkSfxViewShell(const SfxViewShell
* pShell
)
154 return dynamic_cast<const T
*>(pShell
) != nullptr;
157 typedef std::unordered_map
<OUString
, std::pair
<Color
, int>> StylesHighlighterColorMap
;
160 * One SfxViewShell more or less represents one edit window for a document, there can be multiple
161 * ones for a single opened document (SfxObjectShell).
163 class SFX2_DLLPUBLIC SfxViewShell
: public SfxShell
, public SfxListener
, public OutlinerViewShell
, public vcl::ILibreOfficeKitNotifier
165 friend class SfxViewFrame
;
166 friend class SfxBaseController
;
167 friend class SfxPrinterController
;
169 std::unique_ptr
<struct SfxViewShell_Impl
> pImpl
;
170 SfxViewFrame
& rFrame
;
171 VclPtr
<vcl::Window
> pWindow
;
173 bool mbPrinterSettingsModified
;
174 LanguageTag maLOKLanguageTag
;
175 LanguageTag maLOKLocale
;
176 LOKDeviceFormFactor maLOKDeviceFormFactor
;
177 bool mbLOKAccessibilityEnabled
;
178 rtl::Reference
<LOKDocumentFocusListener
> mpLOKDocumentFocusListener
;
179 std::unordered_set
<OUString
> mvLOKBlockedCommandList
;
180 OUString maLOKTimezone
;
181 bool maLOKIsTimezoneSet
;
183 /// Used to set the DocId at construction time. See SetCurrentDocId.
184 static ViewShellDocId mnCurrentDocId
;
186 /// Used for async export
187 std::shared_ptr
<SfxStoringHelper
> m_xHelper
;
189 StylesHighlighterColorMap ParaStylesColorMap
;
190 StylesHighlighterColorMap CharStylesColorMap
;
193 virtual void Activate(bool IsMDIActivate
) override
;
194 virtual void Deactivate(bool IsMDIActivate
) override
;
196 virtual void InnerResizePixel( const Point
&rOfs
, const Size
&rSize
, bool inplaceEditModeChange
);
197 virtual void OuterResizePixel( const Point
&rOfs
, const Size
&rSize
);
198 virtual void SetZoomFactor( const Fraction
&rZoomX
, const Fraction
&rZoomY
);
202 virtual void Notify( SfxBroadcaster
& rBC
, const SfxHint
& rHint
) override
;
206 SAL_WARN_UNUSED_RESULT
static SfxViewShell
* GetFirst( bool bOnlyVisible
= true, const std::function
<bool ( const SfxViewShell
* )>& isViewShell
= nullptr );
207 SAL_WARN_UNUSED_RESULT
static SfxViewShell
* GetNext( const SfxViewShell
& rPrev
,
208 bool bOnlyVisible
= true,
209 const std::function
<bool ( const SfxViewShell
* )>& isViewShell
= nullptr );
210 SAL_WARN_UNUSED_RESULT
static SfxViewShell
* Current();
212 SAL_WARN_UNUSED_RESULT
static SfxViewShell
* Get( const css::uno::Reference
< css::frame::XController
>& i_rController
);
214 // Initialize Constructors/Destructors
215 SFX_DECL_INTERFACE(SFX_INTERFACE_SFXVIEWSH
)
218 /// SfxInterface initializer.
219 static void InitInterface_Impl();
221 LOKDocumentFocusListener
& GetLOKDocumentFocusListener();
222 const LOKDocumentFocusListener
& GetLOKDocumentFocusListener() const;
226 SfxViewShell( SfxViewFrame
& rFrame
, SfxViewShellFlags nFlags
);
227 virtual ~SfxViewShell() override
;
229 SfxInPlaceClient
* GetIPClient() const;
230 SfxInPlaceClient
* GetUIActiveClient() const;
231 SfxInPlaceClient
* FindIPClient( const css::uno::Reference
< css::embed::XEmbeddedObject
>& xObj
, vcl::Window
*pObjParentWin
) const;
233 virtual ErrCode
DoVerb(sal_Int32 nVerb
);
235 void OutplaceActivated( bool bActive
);
236 virtual void UIActivating( SfxInPlaceClient
* pClient
);
237 virtual void UIDeactivated( SfxInPlaceClient
* pClient
);
239 void JumpToMark( const OUString
& rMark
);
240 void VisAreaChanged();
245 * Initialize is called after the frame has been loaded and the controller
246 * has been set. By the time this is called the document has been fully
248 * @param bOnlyASample used by some dialogs to avoid constructing monster strings e.g. in calc
250 virtual bool PrepareClose( bool bUI
= true );
251 virtual OUString
GetSelectionText( bool bCompleteWords
= false, bool bOnlyASample
= false );
252 virtual bool HasSelection( bool bText
= true ) const;
253 virtual SdrView
* GetDrawView() const;
255 void AddSubShell( SfxShell
& rShell
);
256 void RemoveSubShell( SfxShell
*pShell
=nullptr );
257 SfxShell
* GetSubShell( sal_uInt16
);
259 virtual SfxShell
* GetFormShell() { return nullptr; };
260 virtual const SfxShell
* GetFormShell() const { return nullptr; };
262 // ILibreOfficeKitNotifier
263 virtual void notifyWindow(vcl::LOKWindowId nLOKWindowId
, const OUString
& rAction
, const std::vector
<vcl::LOKPayloadItem
>& rPayload
= std::vector
<vcl::LOKPayloadItem
>()) const override
;
265 // Focus, KeyInput, Cursor
266 virtual void ShowCursor( bool bOn
= true );
267 virtual bool KeyInput( const KeyEvent
&rKeyEvent
);
271 vcl::Window
* GetWindow() const { return pWindow
; }
272 weld::Window
* GetFrameWeld() const;
273 void SetWindow( vcl::Window
*pViewPort
);
274 const SvBorder
& GetBorderPixel() const;
275 void SetBorderPixel( const SvBorder
&rBorder
);
276 void InvalidateBorder();
280 This method returns a reference to the <SfxViewFrame> Instance in which
281 this SfxViewShell is displayed. This is the instance that was passed
282 on in the constructor. It is guaranteed that the returned reference
283 is a valid SfxViewFrame instance.
287 <SfxShell::GetFrame()const>
289 SfxViewFrame
& GetViewFrame() const
294 // Printing Interface
295 virtual SfxPrinter
* GetPrinter( bool bCreate
= false );
296 virtual sal_uInt16
SetPrinter( SfxPrinter
*pNewPrinter
, SfxPrinterChangeFlags nDiffFlags
= SFX_PRINTER_ALL
);
297 virtual bool HasPrintOptionsPage() const;
298 virtual std::unique_ptr
<SfxTabPage
> CreatePrintOptionsPage(weld::Container
* pPage
, weld::DialogController
* pController
, const SfxItemSet
&rOptions
);
299 Printer
* GetActivePrinter() const;
302 virtual void WriteUserData( OUString
&, bool bBrowse
= false );
303 virtual void ReadUserData( const OUString
&, bool bBrowse
= false );
304 virtual void WriteUserDataSequence ( css::uno::Sequence
< css::beans::PropertyValue
>& );
305 virtual void ReadUserDataSequence ( const css::uno::Sequence
< css::beans::PropertyValue
>& );
306 virtual void QueryObjAreaPixel( tools::Rectangle
& rRect
) const;
308 virtual SfxObjectShell
* GetObjectShell() override
;
310 /** retrieves the document which shall be considered the "current document" when the frame is active
312 The default implementation simply returns the XModel of the associated SfxObjectShell. You will rarely
313 need to overwrite this behavior.
315 virtual css::uno::Reference
< css::frame::XModel
>
316 GetCurrentDocument() const;
318 /** forwards the current document, as returned by ->GetCurrentDocument, to SfxObjectShell::SetWorkingDocument
320 void SetCurrentDocument() const;
322 /** get an XRenderable instance that can render this document
324 virtual css::uno::Reference
< css::view::XRenderable
> GetRenderable();
327 virtual void MarginChanged();
328 const Size
& GetMargin() const;
329 void SetMargin( const Size
& );
330 void DisconnectAllClients();
331 bool NewWindowAllowed() const { return !bNoNewWindow
; }
332 void SetNewWindowAllowed( bool bSet
) { bNoNewWindow
= !bSet
; }
334 void SetController( SfxBaseController
* pController
);
335 css::uno::Reference
<css::frame::XController
> GetController() const;
337 bool TryContextMenuInterception(const rtl::Reference
<VCLXPopupMenu
>& rIn
,
338 const OUString
& rMenuIdentifier
,
339 rtl::Reference
<VCLXPopupMenu
>& rOut
,
340 css::ui::ContextMenuExecuteEvent aEvent
);
341 bool TryContextMenuInterception(const rtl::Reference
<VCLXPopupMenu
>&,
342 const OUString
& rMenuIdentifier
,
343 css::ui::ContextMenuExecuteEvent aEvent
);
345 void ExecPrint( const css::uno::Sequence
< css::beans::PropertyValue
>&, bool, bool );
346 // Like ExecPrint(), but only sets up for printing. Use Printer::ExecutePrintJob() and Printer::FinishPrintJob() afterwards.
347 void StartPrint( const css::uno::Sequence
< css::beans::PropertyValue
>&, bool, bool );
348 const std::shared_ptr
< vcl::PrinterController
>& GetPrinterController() const;
350 void AddRemoveClipboardListener( const css::uno::Reference
< css::datatransfer::clipboard::XClipboardListener
>&, bool );
351 css::uno::Reference
< css::datatransfer::clipboard::XClipboardNotifier
> GetClipboardNotifier() const;
353 SAL_DLLPRIVATE SfxInPlaceClient
* GetUIActiveIPClient_Impl() const;
354 SAL_DLLPRIVATE
void AddContextMenuInterceptor_Impl( const css::uno::Reference
< css::ui::XContextMenuInterceptor
>& xInterceptor
);
355 SAL_DLLPRIVATE
void RemoveContextMenuInterceptor_Impl( const css::uno::Reference
< css::ui::XContextMenuInterceptor
>& xInterceptor
);
356 SAL_DLLPRIVATE
bool GlobalKeyInput_Impl( const KeyEvent
&rKeyEvent
);
358 SAL_DLLPRIVATE
void NewIPClient_Impl( SfxInPlaceClient
*pIPClient
);
359 SAL_DLLPRIVATE
void IPClientGone_Impl( SfxInPlaceClient
const *pIPClient
);
360 SAL_DLLPRIVATE
void ResetAllClients_Impl( SfxInPlaceClient
const *pIP
);
362 SAL_DLLPRIVATE
void SetPrinter_Impl( VclPtr
<SfxPrinter
>& pNewPrinter
);
364 SAL_DLLPRIVATE
bool HandleNotifyEvent_Impl( NotifyEvent
const & rEvent
);
365 SAL_DLLPRIVATE
bool HasKeyListeners_Impl() const;
366 SAL_DLLPRIVATE
bool HasMouseClickListeners_Impl() const;
368 SAL_DLLPRIVATE SfxBaseController
* GetBaseController_Impl() const;
371 SAL_DLLPRIVATE
void ExecPrint_Impl(SfxRequest
&);
372 SAL_DLLPRIVATE
void ExecMisc_Impl(SfxRequest
&);
373 SAL_DLLPRIVATE
void GetState_Impl(SfxItemSet
&);
374 SAL_DLLPRIVATE
void CheckIPClient_Impl(SfxInPlaceClient
const *, const tools::Rectangle
&);
375 SAL_DLLPRIVATE
void PushSubShells_Impl( bool bPush
=true );
376 SAL_DLLPRIVATE
void PopSubShells_Impl() { PushSubShells_Impl( false ); }
377 SAL_DLLPRIVATE
bool ExecKey_Impl(const KeyEvent
& aKey
);
379 /// Set up a more efficient internal callback instead of LibreOfficeKitCallback.
380 void setLibreOfficeKitViewCallback(SfxLokCallbackInterface
* pCallback
);
381 SfxLokCallbackInterface
* getLibreOfficeKitViewCallback() const;
382 /// dump view state for diagnostics
383 void dumpLibreOfficeKitViewState(rtl::OStringBuffer
&rState
);
384 /// Invokes the registered callback, if there are any.
385 virtual void libreOfficeKitViewCallback(int nType
, const OString
& pPayload
) const override
;
386 virtual void libreOfficeKitViewCallbackWithViewId(int nType
, const OString
& pPayload
, int nViewId
) const override
;
387 virtual void libreOfficeKitViewInvalidateTilesCallback(const tools::Rectangle
* pRect
, int nPart
, int nMode
) const override
;
388 virtual void libreOfficeKitViewUpdatedCallback(int nType
) const override
;
389 virtual void libreOfficeKitViewUpdatedCallbackPerViewId(int nType
, int nViewId
, int nSourceViewId
) const override
;
390 // Performs any pending calls to libreOfficeKitViewInvalidateTilesCallback() as necessary.
391 virtual void flushPendingLOKInvalidateTiles();
392 virtual void libreOfficeKitViewAddPendingInvalidateTiles() override
;
393 // Returns current payload for nType, after libreOfficeKitViewUpdatedCallback() or
394 // libreOfficeKitViewUpdatedCallbackPerViewId() were called. If no payload should
395 // be generated, the ignore flag should be set.
396 virtual std::optional
<OString
> getLOKPayload(int nType
, int nViewId
) const;
398 /// Set if we are doing tiled searching.
399 void setTiledSearching(bool bTiledSearching
);
400 /// See lok::Document::getPart().
401 virtual int getPart() const;
402 /// See lok::Document::getMode().
403 virtual int getEditMode() const;
404 virtual void dumpAsXml(xmlTextWriterPtr pWriter
) const;
405 /// See OutlinerViewShell::GetViewShellId().
406 ViewShellId
GetViewShellId() const override
;
408 /// Set the current DocId, which is used by Mobile LOKit to
409 /// load multiple documents and yet identify the views of each.
410 /// There are events that are fired while creating a new view,
411 /// and if we don't have a DocId, we can't know which other views
412 /// within the same document (if any) should get those events.
413 /// By setting this static value, we are able to set the DocId
414 /// of each SfxViewShell at construction time.
415 static void SetCurrentDocId(ViewShellDocId nId
);
416 /// Get the DocId used by Mobile LOKit to load multiple documents.
417 ViewShellDocId
GetDocId() const override
;
419 /// ILibreOfficeKitNotifier. Emits a LOK_CALLBACK_INVALIDATE_TILES.
420 virtual void notifyInvalidation(tools::Rectangle
const *) const override
;
421 /// See OutlinerViewShell::NotifyOtherViews().
422 void NotifyOtherViews(int nType
, const OString
& rKey
, const OString
& rPayload
) override
;
423 /// See OutlinerViewShell::NotifyOtherView().
424 void NotifyOtherView(OutlinerViewShell
* pOtherShell
, int nType
, const OString
& rKey
, const OString
& rPayload
) override
;
425 /// Ask this view to send its cursor position to pViewShell.
426 virtual void NotifyCursor(SfxViewShell
* /*pViewShell*/) const;
427 /// Where a new view can perform some update/initialization soon after the callback has been registered.
428 virtual void afterCallbackRegistered();
429 /// See OutlinerViewShell::GetEditWindowForActiveOLEObj().
430 virtual vcl::Window
* GetEditWindowForActiveOLEObj() const override
;
432 /// Set the LibreOfficeKit language of this view.
433 void SetLOKLanguageTag(const OUString
& rBcp47LanguageTag
);
434 /// Get the LibreOfficeKit language of this view.
435 const LanguageTag
& GetLOKLanguageTag() const { return maLOKLanguageTag
; }
436 /// Enable/Disable LibreOfficeKit AT support for this view.
437 void SetLOKAccessibilityState(bool bEnabled
);
439 /// Get the LibreOfficeKit timezone of this view. See @SetLOKTimezone.
440 std::pair
<bool, OUString
> GetLOKTimezone() const
442 return { maLOKIsTimezoneSet
, maLOKTimezone
};
445 /// Set the LibreOfficeKit timezone of this view.
446 /// @isSet true to use @rTimezone, even if it's empty. Otherwise, no timezone.
447 /// @rTimezone the value to set (which could be empty).
448 void SetLOKTimezone(bool isSet
, const OUString
& rTimezone
)
450 maLOKIsTimezoneSet
= isSet
;
451 maLOKTimezone
= rTimezone
;
454 /// Set the LibreOfficeKit locale of this view.
455 void SetLOKLocale(const OUString
& rBcp47LanguageTag
);
456 /// Get the LibreOfficeKit locale of this view.
457 const LanguageTag
& GetLOKLocale() const { return maLOKLocale
; }
458 /// Get the form factor of the device where the lok client is running.
459 LOKDeviceFormFactor
GetLOKDeviceFormFactor() const { return maLOKDeviceFormFactor
; }
460 /// Check if the lok client is running on a desktop machine.
461 bool isLOKDesktop() const { return maLOKDeviceFormFactor
== LOKDeviceFormFactor::DESKTOP
; }
462 /// Check if the lok client is running on a tablet.
463 bool isLOKTablet() const { return maLOKDeviceFormFactor
== LOKDeviceFormFactor::TABLET
; }
464 /// Check if the lok client is running on a mobile device.
465 bool isLOKMobilePhone() const { return maLOKDeviceFormFactor
== LOKDeviceFormFactor::MOBILE
; }
467 virtual tools::Rectangle
getLOKVisibleArea() const { return tools::Rectangle(); }
469 // Blocked Command view settings
470 void setBlockedCommandList(const char* blockedCommandList
);
471 bool isBlockedCommand(OUString command
);
473 void SetStoringHelper(std::shared_ptr
<SfxStoringHelper
> xHelper
) { m_xHelper
= xHelper
; }
475 StylesHighlighterColorMap
& GetStylesHighlighterParaColorMap() { return ParaStylesColorMap
; }
476 StylesHighlighterColorMap
& GetStylesHighlighterCharColorMap() { return CharStylesColorMap
; }
478 OUString
getA11yFocusedParagraph() const;
479 int getA11yCaretPosition() const;
482 #endif // INCLUDED_SFX2_VIEWSH_HXX
484 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */