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 <sal/config.h>
23 #include <rtl/ref.hxx>
24 #include <sfx2/docinsert.hxx>
25 #include <sfx2/dockwin.hxx>
26 #include <sfx2/viewsh.hxx>
27 #include <sfx2/ctrlitem.hxx>
28 #include <sfx2/shell.hxx>
29 #include <sfx2/viewfrm.hxx>
30 #include <vcl/InterimItemWindow.hxx>
31 #include <vcl/timer.hxx>
32 #include "document.hxx"
33 #include "edit.hxx"
34 
35 class SmViewShell;
36 class SmPrintUIOptions;
37 class SmGraphicAccessible;
38 class SmGraphicWidget;
39 class SmElementsDockingWindow;
40 
41 namespace svtools { class ColorConfig; }
42 
43 class SmGraphicWindow final : public InterimItemWindow
44 {
45 private:
46     Point aPixOffset; // offset to virtual window (pixel)
47     Size aTotPixSz; // total size of virtual window (pixel)
48     tools::Long nLinePixH; // size of a line/column (pixel)
49     tools::Long nColumnPixW;
50     sal_uInt16 nZoom;
51 
52     std::unique_ptr<weld::ScrolledWindow> mxScrolledWindow;
53     std::unique_ptr<SmGraphicWidget> mxGraphic;
54     std::unique_ptr<weld::CustomWeld> mxGraphicWin;
55 
56     DECL_LINK(ScrollHdl, weld::ScrolledWindow&, void);
57 
58     void SetGraphicMapMode(const MapMode& rNewMapMode);
59     MapMode GetGraphicMapMode() const;
60 
61 public:
62     explicit SmGraphicWindow(SmViewShell& rShell);
63     virtual void dispose() override;
64     virtual ~SmGraphicWindow() override;
65 
66     void SetTotalSize(const Size& rNewSize);
67     Size GetTotalSize() const;
68 
69     void SetZoom(sal_uInt16 Factor);
GetZoom() const70     sal_uInt16 GetZoom() const { return nZoom; }
71 
72     void ZoomToFitInWindow();
73 
74     virtual void Resize() override;
75     void ShowContextMenu(const CommandEvent& rCEvt);
76 
GetGraphicWidget()77     SmGraphicWidget& GetGraphicWidget()
78     {
79         return *mxGraphic;
80     }
81 
GetGraphicWidget() const82     const SmGraphicWidget& GetGraphicWidget() const
83     {
84         return *mxGraphic;
85     }
86 };
87 
88 class SmGraphicWidget final : public weld::CustomWidgetController
89 {
90 public:
IsCursorVisible() const91     bool IsCursorVisible() const
92     {
93         return bIsCursorVisible;
94     }
95     void ShowCursor(bool bShow);
IsLineVisible() const96     bool IsLineVisible() const
97     {
98         return bIsLineVisible;
99     }
100     void ShowLine(bool bShow);
101     const SmNode * SetCursorPos(sal_uInt16 nRow, sal_uInt16 nCol);
102 
103     explicit SmGraphicWidget(SmViewShell& rShell, SmGraphicWindow& rGraphicWindow);
104     virtual ~SmGraphicWidget() override;
105 
106     // CustomWidgetController
107     virtual void SetDrawingArea(weld::DrawingArea* pDrawingArea) override;
108     virtual bool MouseButtonDown(const MouseEvent &rMEvt) override;
109     virtual bool MouseMove(const MouseEvent &rMEvt) override;
110     virtual void GetFocus() override;
111     virtual void LoseFocus() override;
112 
113     void SetTotalSize();
114 
GetView()115     SmViewShell& GetView()
116     {
117         return mrViewShell;
118     }
119 
GetFormulaDrawPos() const120     const Point& GetFormulaDrawPos() const
121     {
122         return aFormulaDrawPos;
123     }
124 
125     // for Accessibility
126     virtual css::uno::Reference<css::accessibility::XAccessible> CreateAccessible() override;
127 
GetAccessible_Impl()128     SmGraphicAccessible* GetAccessible_Impl()
129     {
130         return mxAccessible.get();
131     }
132 
133 private:
SetIsCursorVisible(bool bVis)134     void SetIsCursorVisible(bool bVis)
135     {
136         bIsCursorVisible = bVis;
137     }
138     void SetCursor(const SmNode *pNode);
139     void SetCursor(const tools::Rectangle &rRect);
140     static bool IsInlineEditEnabled();
141 
142     virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&) override;
143     virtual bool KeyInput(const KeyEvent& rKEvt) override;
144     virtual bool Command(const CommandEvent& rCEvt) override;
145 
146     void RepaintViewShellDoc();
147     DECL_LINK(CaretBlinkTimerHdl, Timer *, void);
148     void CaretBlinkInit();
149     void CaretBlinkStart();
150     void CaretBlinkStop();
151 
152     SmGraphicWindow& mrGraphicWindow;
153 
154     Point aFormulaDrawPos;
155     // old style editing pieces
156     tools::Rectangle aCursorRect;
157     bool bIsCursorVisible;
158     bool bIsLineVisible;
159     AutoTimer aCaretBlinkTimer;
160     rtl::Reference<SmGraphicAccessible> mxAccessible;
161     SmViewShell& mrViewShell;
162 };
163 
164 class SmGraphicController final : public SfxControllerItem
165 {
166     SmGraphicWidget &rGraphic;
167 public:
168     SmGraphicController(SmGraphicWidget &, sal_uInt16, SfxBindings & );
169     virtual void StateChanged(sal_uInt16             nSID,
170                               SfxItemState       eState,
171                               const SfxPoolItem* pState) override;
172 };
173 
174 class SmEditController final : public SfxControllerItem
175 {
176     SmEditWindow &rEdit;
177 
178 public:
179     SmEditController(SmEditWindow &, sal_uInt16, SfxBindings  & );
180 
181     virtual void StateChanged(sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem* pState) override;
182 };
183 
184 class SmCmdBoxWindow : public SfxDockingWindow
185 {
186     std::unique_ptr<SmEditWindow, o3tl::default_delete<SmEditWindow>> m_xEdit;
187     SmEditController    aController;
188     bool                bExiting;
189 
190     Timer               aInitialFocusTimer;
191 
192     DECL_LINK(InitialFocusTimerHdl, Timer *, void);
193 
194 protected:
195 
196     virtual Size CalcDockingSize(SfxChildAlignment eAlign) override;
197     virtual SfxChildAlignment CheckAlignment(SfxChildAlignment eActual,
198                                              SfxChildAlignment eWish) override;
199 
200     virtual void    ToggleFloatingMode() override;
201 
202 public:
203     SmCmdBoxWindow(SfxBindings    *pBindings,
204                    SfxChildWindow *pChildWindow,
205                    Window         *pParent);
206 
207     virtual ~SmCmdBoxWindow () override;
208     virtual void dispose() override;
209 
210     // Window
211     virtual void GetFocus() override;
212     virtual void StateChanged( StateChangedType nStateChange ) override;
213     virtual void Command(const CommandEvent& rCEvt) override;
214 
215     Point WidgetToWindowPos(const weld::Widget& rWidget, const Point& rPos);
216 
217     void ShowContextMenu(const Point& rPos);
218 
219     void AdjustPosition();
220 
GetEditWindow()221     SmEditWindow& GetEditWindow()
222     {
223         return *m_xEdit;
224     }
225     SmViewShell* GetView();
226 };
227 
228 class SmCmdBoxWrapper final : public SfxChildWindow
229 {
230     SFX_DECL_CHILDWINDOW_WITHID(SmCmdBoxWrapper);
231 
232     SmCmdBoxWrapper(vcl::Window* pParentWindow, sal_uInt16 nId, SfxBindings* pBindings, SfxChildWinInfo* pInfo);
233 
234 public:
235 
GetEditWindow()236     SmEditWindow& GetEditWindow()
237     {
238         return static_cast<SmCmdBoxWindow *>(GetWindow())->GetEditWindow();
239     }
240 };
241 
242 namespace sfx2 { class FileDialogHelper; }
243 
244 class SmViewShell: public SfxViewShell
245 {
246     std::unique_ptr<sfx2::DocumentInserter> mpDocInserter;
247     std::unique_ptr<SfxRequest> mpRequest;
248     VclPtr<SmGraphicWindow> mxGraphicWindow;
249     SmGraphicController maGraphicController;
250     OUString maStatusText;
251     bool mbPasteState;
252     /** Used to determine whether insertions using SID_INSERTSPECIAL and SID_INSERTCOMMANDTEXT
253      * should be inserted into SmEditWindow or directly into the SmDocShell as done if the
254      * visual editor was last to have focus.
255      */
256     bool mbInsertIntoEditWindow;
257 
258     DECL_LINK( DialogClosedHdl, sfx2::FileDialogHelper*, void );
259     virtual void            Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) override;
260 
261 protected:
262 
263     static Size GetTextLineSize(OutputDevice const & rDevice,
264                          const OUString& rLine);
265     static Size GetTextSize(OutputDevice const & rDevice,
266                      const OUString& rText,
267                      tools::Long          MaxWidth);
268     static void DrawTextLine(OutputDevice& rDevice,
269                       const Point&  rPosition,
270                       const OUString& rLine);
271     static void DrawText(OutputDevice& rDevice,
272                   const Point&  rPosition,
273                   const OUString& rText,
274                   sal_uInt16        MaxWidth);
275 
276     virtual SfxPrinter *GetPrinter(bool bCreate = false) override;
277     virtual sal_uInt16 SetPrinter(SfxPrinter *pNewPrinter,
278                               SfxPrinterChangeFlags nDiffFlags = SFX_PRINTER_ALL) override;
279 
280     void Insert( SfxMedium& rMedium );
281     void InsertFrom(SfxMedium &rMedium);
282 
283     virtual bool HasPrintOptionsPage() const override;
284     virtual std::unique_ptr<SfxTabPage> CreatePrintOptionsPage(weld::Container* pPage, weld::DialogController* pController,
285                                                                const SfxItemSet &rOptions) override;
286     virtual void Deactivate(bool IsMDIActivate) override;
287     virtual void Activate(bool IsMDIActivate) override;
288     virtual void InnerResizePixel(const Point &rOfs, const Size  &rSize, bool inplaceEditModeChange) override;
289     virtual void OuterResizePixel(const Point &rOfs, const Size  &rSize) override;
290     virtual void QueryObjAreaPixel( tools::Rectangle& rRect ) const override;
291     virtual void SetZoomFactor( const Fraction &rX, const Fraction &rY ) override;
292 
293 public:
294 
295     SmViewShell(SfxViewFrame *pFrame, SfxViewShell *pOldSh);
296     virtual ~SmViewShell() override;
297 
GetDoc()298     SmDocShell * GetDoc()
299     {
300         return static_cast<SmDocShell *>( GetViewFrame()->GetObjectShell() );
301     }
302 
303     SmEditWindow * GetEditWindow();
304 
GetGraphicWidget()305     SmGraphicWidget& GetGraphicWidget()
306     {
307         return mxGraphicWindow->GetGraphicWidget();
308     }
GetGraphicWidget() const309     const SmGraphicWidget& GetGraphicWidget() const
310     {
311         return mxGraphicWindow->GetGraphicWidget();
312     }
313 
GetGraphicWindow()314     SmGraphicWindow& GetGraphicWindow()
315     {
316         return *mxGraphicWindow;
317     }
318 
319     SmElementsDockingWindow* GetDockingWindow();
320 
321     void        SetStatusText(const OUString& rText);
322 
323     void        ShowError( const SmErrorDesc *pErrorDesc );
324     void        NextError();
325     void        PrevError();
326 
327     SFX_DECL_INTERFACE(SFX_INTERFACE_SMA_START+SfxInterfaceId(2))
328     SFX_DECL_VIEWFACTORY(SmViewShell);
329 
330 private:
331     /// SfxInterface initializer.
332     static void InitInterface_Impl();
333 
334 public:
335     void Execute( SfxRequest& rReq );
336     void GetState(SfxItemSet &);
337 
338     void Impl_Print( OutputDevice &rOutDev, const SmPrintUIOptions &rPrintUIOptions,
339             tools::Rectangle aOutRect );
340 
341     /** Set bInsertIntoEditWindow so we know where to insert
342      *
343      * This method is called whenever SmGraphicWidget or SmEditWindow gets focus,
344      * so that when text is inserted from catalog or elsewhere we know whether to
345      * insert for the visual editor, or the text editor.
346      */
SetInsertIntoEditWindow(bool bEditWindowHadFocusLast)347     void SetInsertIntoEditWindow(bool bEditWindowHadFocusLast){
348         mbInsertIntoEditWindow = bEditWindowHadFocusLast;
349     }
350     static bool IsInlineEditEnabled();
351 
352 private:
353     void ZoomByItemSet(const SfxItemSet *pSet);
354 };
355 
356 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
357