1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #pragma once
21 
22 #include <rtl/ref.hxx>
23 
24 #include <sfx2/viewsh.hxx>
25 #include <vcl/prntypes.hxx>
26 #include <vcl/scrbar.hxx>
27 #include <o3tl/deleter.hxx>
28 #include <pres.hxx>
29 #include "View.hxx"
30 #include "fupoor.hxx"
31 #include <sddllapi.h>
32 
33 #include <memory>
34 
35 class SdPage;
36 class SvxRuler;
37 class SdrOle2Obj;       // for the ones, who have undefined parts of SVDRAW
38 class SdDrawDocument;
39 
40 namespace weld
41 {
42     class Window;
43 }
44 
45 namespace com::sun::star::drawing { class XDrawSubController; }
46 
47 namespace sd {
48 
49 class DrawDocShell;
50 class FrameView;
51 class LayerTabBar;
52 class ViewShellBase;
53 class Window;
54 class WindowUpdater;
55 class ZoomList;
56 
57 #undef OUTPUT_DRAWMODE_COLOR
58 #undef OUTPUT_DRAWMODE_CONTRAST
59 
60 const DrawModeFlags OUTPUT_DRAWMODE_COLOR = DrawModeFlags::Default;
61 const DrawModeFlags OUTPUT_DRAWMODE_GRAYSCALE
62         = DrawModeFlags::GrayLine | DrawModeFlags::GrayFill
63         | DrawModeFlags::BlackText | DrawModeFlags::GrayBitmap
64         | DrawModeFlags::GrayGradient;
65 const DrawModeFlags OUTPUT_DRAWMODE_BLACKWHITE
66         = DrawModeFlags::BlackLine | DrawModeFlags::BlackText
67         | DrawModeFlags::WhiteFill | DrawModeFlags::GrayBitmap
68         | DrawModeFlags::WhiteGradient;
69 const DrawModeFlags OUTPUT_DRAWMODE_CONTRAST
70         = DrawModeFlags::SettingsLine | DrawModeFlags::SettingsFill
71         | DrawModeFlags::SettingsText | DrawModeFlags::SettingsGradient;
72 
73 /** Base class of the stacked shell hierarchy.
74 
75     <p>Despite its name this class is not a descendant of SfxViewShell
76     but of SfxShell.  Its name expresses the fact that it acts like a
77     view shell.  Being a stacked shell rather than being an actual view shell
78     there can be several instances of this class that
79     <ul>
80     <li>all are based on the same view shell and thus show the same
81     document and share common view functionality and</li>
82     <li>are all visible at the same time and live in the same
83     frame.</li>
84     <ul></p>
85 
86     <p>This class replaces the former ViewShell class.</p>
87 */
88 class SAL_DLLPUBLIC_RTTI ViewShell
89     : public SfxShell
90 {
91 public:
92     enum ShellType {
93         ST_NONE,
94         ST_DRAW,         // The Draw application.
95         ST_IMPRESS,      // Main view of the Impress application.
96         ST_NOTES,
97         ST_HANDOUT,
98         ST_OUTLINE,
99         ST_SLIDE_SORTER,
100         ST_PRESENTATION,
101         ST_SIDEBAR
102     };
103     static const int MAX_HSPLIT_CNT = 1;
104     static const int MAX_VSPLIT_CNT = 1;
105     static const int MIN_SCROLLBAR_SIZE = 50;
106 
107 
108     ViewShell (
109         vcl::Window* pParentWindow,
110         ViewShellBase& rViewShellBase);
111     virtual ~ViewShell() override;
112 
113     /** The Init method has to be called from the outside directly
114         after a new object of this class has been created.  It can be
115         used for that part of the initialisation that can be run only
116         after the creation of the new object is finished.  This
117         includes registration as listener at event broadcasters.
118 
119         Derived classes should call this method at the head of their
120         Init() methods.
121         @param bIsMainViewShell
122             This flag tells the Init() method whether the new ViewShell will
123             be the main view shell.
124     */
125     virtual void Init (bool bIsMainViewShell);
126 
127     /** The Exit() method has to be called before the destructor so that the
128         view shell is still a valid object and can safely call methods that
129         rely on that.
130     */
131     void Exit();
132 
133     void Cancel();
134 
135     /** Return the window that is the parent of all controls of this view
136         shell.  This may or may not be the window of the frame.
137     */
GetParentWindow() const138     vcl::Window* GetParentWindow() const { return mpParentWindow; }
139 
140     sd::Window* GetContentWindow() const;
141 
GetView() const142     ::sd::View* GetView() const { return mpView; }
143     inline SdrView* GetDrawView() const;
144     SD_DLLPUBLIC DrawDocShell* GetDocSh() const;
145 
146     SdDrawDocument*  GetDoc() const;
147 
148     SD_DLLPUBLIC SfxViewFrame* GetViewFrame() const;
149 
150     /** The active window is usually the mpContentWindow.  When there is a
151         show running then the active window is a ShowWindow.
152     */
GetActiveWindow() const153     ::sd::Window* GetActiveWindow() const { return mpActiveWindow;}
154     SD_DLLPUBLIC weld::Window* GetFrameWeld() const;
155 
156     /** Set the active window.  When the shell is displayed in the center
157         pane then the window of the ViewShellBase is also set to the given
158         window.
159     */
160     void SetActiveWindow (::sd::Window* pWindow);
161 
162     /** Return the rectangle that encloses all windows of the view.  That
163         excludes the controls in the frame like rulers, scroll bars, tab
164         bar, and buttons.
165         @return
166             The rectangle is returned in screen coordinates, i.e. pixel
167             values relative to the upper left corner of the screen?.
168     */
169     const ::tools::Rectangle& GetAllWindowRect();
170 
171     // Mouse- & Key-Events
172     virtual void PrePaint();
173     virtual void Paint (const ::tools::Rectangle& rRect, ::sd::Window* pWin);
174     virtual bool KeyInput(const KeyEvent& rKEvt, ::sd::Window* pWin);
175     virtual void MouseMove(const MouseEvent& rMEvt, ::sd::Window* pWin);
176     virtual void MouseButtonUp(const MouseEvent& rMEvt, ::sd::Window* pWin);
177     virtual void MouseButtonDown(const MouseEvent& rMEvt, ::sd::Window* pWin);
178     virtual void Command(const CommandEvent& rCEvt, ::sd::Window* pWin);
179     bool RequestHelp( const HelpEvent& rEvt );
180     bool Notify( NotifyEvent const & rNEvt, ::sd::Window* pWin );
181 
182     bool HandleScrollCommand(const CommandEvent& rCEvt, ::sd::Window* pWin);
183 
184     void SetUIUnit(FieldUnit eUnit);
185     void SetDefTabHRuler( sal_uInt16 nDefTab );
186 
187     const SfxPoolItem* GetNumBulletItem(SfxItemSet& aNewAttr, sal_uInt16& nNumItemId);
188 
HasRuler() const189     bool HasRuler() const { return mbHasRulers;}
190     void SetRuler(bool bRuler);
191     // Hides horizontal, vertical scrollbar as well as scrollbox
192     void SetScrollBarsVisible(bool bVisible);
193 
194     /** Set internal values of all scroll bars that determine thumb size and
195         position.  The external values like size and position of the scroll
196         bar controls are not modified.
197     */
198     virtual void UpdateScrollBars();
199     void    Scroll(::tools::Long nX, ::tools::Long nY);
200     void    ScrollLines(::tools::Long nX, ::tools::Long nY);
201     virtual void    SetZoom(::tools::Long nZoom);
202     ::tools::Long    GetZoom() const;
203     virtual void    SetZoomRect(const ::tools::Rectangle& rZoomRect);
204     void    InitWindows(const Point& rViewOrigin, const Size& rViewSize,
205                         const Point& rWinPos, bool bUpdate = false);
206     void    InvalidateWindows();
207     /** This method is still used by the OutlineViewShell to update the
208         model according to the content of the outline view.  This in turn
209         updates the previews in the slide sorter.
210     */
211     virtual void UpdatePreview (SdPage* pPage);
212 
213     void    DrawMarkRect(const ::tools::Rectangle& rRect) const;
214 
215     void    ExecReq( SfxRequest &rReq );
216 
GetZoomList()217     ZoomList* GetZoomList() { return mpZoomList.get();}
218 
GetFrameView()219     FrameView* GetFrameView() { return mpFrameView; }
220     /** Setting a frame view triggers ReadFrameViewData() for the new
221         frame.
222         @param pFrameView
223             The new frame view that replaces the old one.
224     */
225     void SetFrameView (FrameView* pFrameView);
226     virtual void  ReadFrameViewData(FrameView* pView);
227     virtual void  WriteFrameViewData();
228     void  WriteUserData();
229     void  ReadUserData();
230 
231     virtual bool ActivateObject(SdrOle2Obj* pObj, sal_Int32 nVerb);
232 
233     /** @returns
234             current or selected page or 0. This method
235             will fail in master page mode.
236 
237         @deprecated, please use getCurrentPage();
238     */
239     virtual SdPage* GetActualPage() = 0;
240 
241     /** @returns
242             current or selected page or 0.
243     */
244     virtual SdPage* getCurrentPage() const = 0;
245 
GetOldFunction() const246     const rtl::Reference<FuPoor>& GetOldFunction() const { return mxOldFunction; }
HasOldFunction() const247     bool HasOldFunction() const { return mxOldFunction.is(); }
GetCurrentFunction() const248     const rtl::Reference<FuPoor>& GetCurrentFunction() const { return mxCurrentFunction; }
HasCurrentFunction(sal_uInt16 nSID)249     bool HasCurrentFunction( sal_uInt16 nSID ) { return mxCurrentFunction.is() && (mxCurrentFunction->GetSlotID() == nSID ); }
HasCurrentFunction() const250     bool HasCurrentFunction() const { return mxCurrentFunction.is(); }
251 
252     void SetCurrentFunction(const rtl::Reference<FuPoor>& xFunction);
253     void SetOldFunction(const rtl::Reference<FuPoor>& xFunction);
254     void DeactivateCurrentFunction( bool bPermanent = false );
255 
256     void    SetPageSizeAndBorder(PageKind ePageKind, const Size& rNewSize,
257                             ::tools::Long nLeft, ::tools::Long nRight, ::tools::Long nUpper, ::tools::Long nLower,
258                             bool bScaleAll, Orientation eOrient, sal_uInt16 nPaperBin,
259                             bool bBackgroundFullSize );
260 
SetStartShowWithDialog(bool bIn)261     void    SetStartShowWithDialog( bool bIn ) { mbStartShowWithDialog = bIn; }
IsStartShowWithDialog() const262     bool    IsStartShowWithDialog() const { return mbStartShowWithDialog; }
263 
GetPrintedHandoutPageNum() const264     sal_uInt16 GetPrintedHandoutPageNum() const { return mnPrintedHandoutPageNum; }
SetPrintedHandoutPageNum(sal_uInt16 nPageNumber)265     void SetPrintedHandoutPageNum (sal_uInt16 nPageNumber) {mnPrintedHandoutPageNum=nPageNumber; }
266 
GetPrintedHandoutPageCount() const267     sal_uInt16 GetPrintedHandoutPageCount() const { return mnPrintedHandoutPageCount; }
SetPrintedHandoutPageCount(sal_uInt16 nPageCount)268     void SetPrintedHandoutPageCount (sal_uInt16 nPageCount) {mnPrintedHandoutPageCount=nPageCount; }
269 
270     virtual bool PrepareClose( bool bUI = true );
271 
272     void GetMenuState(SfxItemSet& rSet);
273 
274     virtual sal_Int8 AcceptDrop( const AcceptDropEvent& rEvt, DropTargetHelper& rTargetHelper,
275                                  ::sd::Window* pTargetWindow, sal_uInt16 nPage, SdrLayerID nLayer );
276     virtual sal_Int8 ExecuteDrop( const ExecuteDropEvent& rEvt, DropTargetHelper& rTargetHelper,
277                                   ::sd::Window* pTargetWindow, sal_uInt16 nPage, SdrLayerID nLayer );
278 
279     virtual void WriteUserDataSequence ( css::uno::Sequence < css::beans::PropertyValue >& );
280     virtual void ReadUserDataSequence ( const css::uno::Sequence < css::beans::PropertyValue >& );
281 
282     /** this method is called when the visible area of the view from this viewshell is changed */
283     virtual void VisAreaChanged(const ::tools::Rectangle& rRect);
284 
285     /** Create an accessible object representing the specified window.
286         Override this method to provide view mode specific objects.  The
287         default implementation returns an empty reference.
288         @param pWindow
289             Make the document displayed in this window accessible.
290         @return
291             This default implementation returns an empty reference.
292     */
293     virtual css::uno::Reference<css::accessibility::XAccessible>
294         CreateAccessibleDocumentView (::sd::Window* pWindow);
295 
296     virtual void SwitchViewFireFocus( const css::uno::Reference< css::accessibility::XAccessible >& xAcc );
297     void SwitchActiveViewFireFocus( );
298     // Move these two methods from DrawViewShell to enable slide show view
299     void    NotifyAccUpdate();
300     void    fireSwitchCurrentPage(sal_Int32 pageIndex);
301     void SetWinViewPos(const Point& rWinPos);
302     Point const & GetWinViewPos() const;
303     Point const & GetViewOrigin() const;
304 
305     /** Return the window updater of this view shell.
306         @return
307             In rare circumstances the returned pointer may be <null/>,
308             i.e. when no memory is available anymore.
309     */
310     ::sd::WindowUpdater* GetWindowUpdater() const;
311 
312     /** Return the border that is drawn around the actual document view.
313         The border contains typically rulers and scroll bars.
314     */
315     SvBorder GetBorder();
316 
317     /** Notify the view shell that its parent window has been resized.
318         The ViewShell places and resizes its UI elements accordingly.
319         The new size can be obtained from the parent window.
320     */
321     virtual void Resize();
322 
323     /** Set position and size of the GUI elements that are controlled by
324         the view shell like rulers and scroll bars as well as the actual
325         document view according to the position and size that were given
326         with the last Resize() call.
327     */
328     virtual void ArrangeGUIElements();
329 
330     //  virtual void OuterResizePixel(const Point &rPos, const Size &rSize);
331     //  virtual void InnerResizePixel(const Point &rPos, const Size &rSize);
332 
333     // Exported for unit test
334     SD_DLLPUBLIC ViewShellBase& GetViewShellBase() const;
335 
336     /** Return <TRUE/> when the called view shell is the main sub shell of
337         its ViewShellBase object, i.e. is display in the center pane.  This
338         convenience function is equivalent to comparing the this pointer to
339         the result of ViewShellBase::GetViewShell(PT_CENTER).
340     */
341     bool IsMainViewShell() const;
342 
343     /** Set or reset the flag that indicates whether the called shell is the
344         one displayed in the center pane.  By default this flag is set to
345         <FALSE/>.  For the main view shell it thus has to be set to <TRUE/>.
346     */
347     void SetIsMainViewShell (bool bIsMainViewShell);
348 
349     /** Return a sub controller that implements the view shell specific
350         part of the DrawController.
351     */
352     virtual css::uno::Reference<css::drawing::XDrawSubController> CreateSubController() = 0;
353 
354     /** Return the type of the shell.
355     */
356     SD_DLLPUBLIC ShellType GetShellType() const; //Export for unit test
357 
358     /** This method is more or less an alias to Deactivate().  It is called
359         before an object of this class is taken from the stack of view
360         shells.
361 
362         <p>When this method is not called before a view shell is taken from
363         a stack then the Deactivate() call from the SFX as a response to
364         RemoveSubShell() comes too late when the view shell is not on the
365         stack anymore.</p>
366     */
367     virtual void Shutdown();
368 
369     /** This function is called from the underlying ViewShellBase
370         object to handle a verb execution request.
371     */
372     virtual ErrCode DoVerb(sal_Int32 nVerb);
373 
374     virtual void UIActivating( SfxInPlaceClient* );
375     virtual void UIDeactivated( SfxInPlaceClient* );
376 
377     /** Show controls of the UI or hide them, depending on the given flag.
378         As a result the border is adapted.
379     */
380     virtual void ShowUIControls (bool bVisible);
381     bool IsPageFlipMode() const;
382 
383     /** Set the given window as new parent window.  This is not possible for
384         all views, so the return value tells the caller if the relocation
385         was successful.
386     */
387     virtual bool RelocateToParentWindow (vcl::Window* pParentWindow);
388 
389     /** Depending on the given request create a new page or duplicate an
390         existing one.  A new page is created behind the given slide.
391         @param rRequest
392             The request as passed to an Execute() method.  Its arguments are
393             evaluated.  Its slot id determines whether to create or
394             duplicate a slide.
395         @param pPage
396             This page is either duplicated or becomes the predecessor of the
397             new slide.  If NULL a duplication request is ignored.  A new
398             slide is inserted as first slide.
399         @param nInsertPosition
400             When -1 (the default) then insert after pPage.  Otherwise insert
401             before the given index (of a standard page).
402         @return
403             The new slide is returned.  If for some reason a new page can
404             not be created then NULL is returned.
405     */
406     virtual SdPage* CreateOrDuplicatePage (
407         SfxRequest& rRequest,
408         PageKind ePageKind,
409         SdPage* pPage,
410         const sal_Int32 nInsertPosition = -1);
411 
412     /// Allows adjusting the point or mark of the selection to a document coordinate.
413     void SetCursorMm100Position(const Point& rPosition, bool bPoint, bool bClearMark);
414     /// Gets the current selection
415     css::uno::Reference<css::datatransfer::XTransferable> GetSelectionTransferrable() const;
416     /// Allows starting or ending a graphic move or resize action.
417     void SetGraphicMm100Position(bool bStart, const Point& rPosition);
418 
419     class Implementation;
420 
421 protected:
422     /** must be called in the beginning of each subclass d'tor.
423         disposes and clears both current and old function. */
424     void DisposeFunctions();
425 
426     friend class ViewShellBase;
427 
428     /** Window inside the rulers and scroll bars that shows a view of the
429         document.
430     */
431 
432     VclPtr<sd::Window> mpContentWindow;
433 
434     /// Horizontal scroll bar for the current slide is displayed when needed.
435     VclPtr<ScrollBar> mpHorizontalScrollBar;
436     /// Vertical scroll bar for whole document is always visible.
437     VclPtr<ScrollBar> mpVerticalScrollBar;
438     /// Horizontal ruler is not shown by default.
439     VclPtr<SvxRuler> mpHorizontalRuler;
440     /// Vertical ruler is not shown by default.
441     VclPtr<SvxRuler> mpVerticalRuler;
442     /// Filler of the little square enclosed by the two scroll bars.
443     VclPtr<ScrollBarBox> mpScrollBarBox;
444     /// Layer tab bar.
445     VclPtr<LayerTabBar> mpLayerTabBar;
446 
447     /// This flag controls whether the rulers are visible.
448     bool mbHasRulers;
449 
450     /// The active window.
451     VclPtr< ::sd::Window> mpActiveWindow;
452     ::sd::View* mpView;
453     FrameView*  mpFrameView;
454 
455     rtl::Reference<FuPoor>   mxCurrentFunction;
456     rtl::Reference<FuPoor>   mxOldFunction;
457     std::unique_ptr<ZoomList> mpZoomList;
458 
459     Point       maViewPos;
460     Size        maViewSize;
461     Size        maScrBarWH;
462 
463     bool        mbStartShowWithDialog;    // presentation is started by dialog
464     sal_uInt16      mnPrintedHandoutPageNum; // Page number of the handout page that is to be printed.
465     sal_uInt16      mnPrintedHandoutPageCount; // Page count of the handout pages that are to be printed.
466 
467     //af    bool        bPrintDirectSelected;       // Print only selected objects in direct print
468     //afString      sPageRange;                 // pagerange if selected objects in direct print
469 
470     /** Area covered by all windows, i.e. the area of the parent window
471         without the controls at the borders like rulers, scroll bars, tab
472         bar, buttons.
473         This rectangle may be set in window coordinates (i.e. pixel values
474         relative to the parent window).  It is transformed by every call to
475         GetAllWindowRectangle() into screen coordinates (relative to the
476         upper left corner of the screen.
477     */
478     ::tools::Rectangle maAllWindowRectangle;
479 
480     /// The type of the shell.  Returned by GetShellType().
481     ShellType meShellType;
482 
483     std::unique_ptr<Implementation, o3tl::default_delete<Implementation>> mpImpl;
484 
485     // Support methods for centralized UNDO/REDO
486     virtual SfxUndoManager* ImpGetUndoManager() const;
487     void ImpGetUndoStrings(SfxItemSet &rSet) const;
488     void ImpGetRedoStrings(SfxItemSet &rSet) const;
489     void ImpSidUndo(SfxRequest& rReq);
490     void ImpSidRedo(SfxRequest& rReq);
491 
492     DECL_LINK( HScrollHdl, ScrollBar *, void );
493     DECL_LINK( VScrollHdl, ScrollBar *, void );
494 
495     // virtual scroll handler, here, derivative classes can add themselves here
496     virtual void VirtHScrollHdl(ScrollBar* pHScroll);
497     virtual void VirtVScrollHdl(ScrollBar* pVScroll);
498 
499     // virtual functions ruler handling
500     virtual VclPtr<SvxRuler> CreateHRuler(::sd::Window* pWin);
501     virtual VclPtr<SvxRuler> CreateVRuler(::sd::Window* pWin);
502     virtual void UpdateHRuler();
503     virtual void UpdateVRuler();
504 
505     virtual void Activate(bool IsMDIActivate) override;
506     virtual void Deactivate(bool IsMDIActivate) override;
507 
508     virtual void SetZoomFactor( const Fraction &rZoomX,
509                                 const Fraction &rZoomY );
510 
511     /**
512         This must be called after the ctor, but before anything else.
513         It's the part of construction that is dependent
514         on showing the top-level window.
515 
516         Showing a window with a11y enabled causes various callbacks
517         to be triggered.
518 
519         Due to the "virtual methods are not virtual during constructors"
520         problem, this is a disaster to call from the ctor
521 
522         i.e. construct calls Show, and if a11y is enabled this
523         reenters the not-fully constructed object and calls
524         CreateAccessibleDocumentView, so if construct is called
525         from the ctor then if a derived class is constructed the base-case
526         CreateAccessibleDocumentView is used, not the derived
527         CreateAccessibleDocumentView. i.e. run smoketest under a11y with
528         debugging assertions enabled
529     */
530     void doShow();
531 
532 private:
533     VclPtr<vcl::Window> mpParentWindow;
534     /** This window updater is used to keep all relevant windows up to date
535         with reference to the digit language used to display digits in text
536         shapes.
537     */
538     ::std::unique_ptr< ::sd::WindowUpdater> mpWindowUpdater;
539 
540     /** Code common to all constructors.  It generally is a bad idea
541         to call this function from outside a constructor.
542     */
543     void construct();
544 
545     /** Create the rulers.
546     */
547     void SetupRulers();
548 };
549 
GetDrawView() const550 SdrView* ViewShell::GetDrawView() const
551 {
552     return static_cast<SdrView*>(mpView);
553 }
554 
555 } // end of namespace sd
556 
557 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
558