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