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