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