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 #ifndef INCLUDED_CHART2_SOURCE_CONTROLLER_MAIN_CHARTCONTROLLER_HXX
20 #define INCLUDED_CHART2_SOURCE_CONTROLLER_MAIN_CHARTCONTROLLER_HXX
21 
22 #include <LifeTime.hxx>
23 #include "CommandDispatchContainer.hxx"
24 #include "SelectionHelper.hxx"
25 
26 #include <svx/svdtypes.hxx>
27 #include <vcl/timer.hxx>
28 
29 #include <cppuhelper/implbase.hxx>
30 #include <salhelper/simplereferenceobject.hxx>
31 
32 #include <com/sun/star/frame/XDispatchProvider.hpp>
33 #include <com/sun/star/ui/XContextMenuInterception.hpp>
34 #include <com/sun/star/util/XModeChangeListener.hpp>
35 #include <com/sun/star/util/XCloseListener.hpp>
36 #include <com/sun/star/util/XModifyListener.hpp>
37 #include <com/sun/star/frame/XController.hpp>
38 #include <com/sun/star/frame/XLayoutManagerListener.hpp>
39 #include <com/sun/star/lang/XServiceInfo.hpp>
40 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
41 
42 #include <memory>
43 #include <set>
44 
45 namespace com { namespace sun { namespace star { namespace accessibility { class XAccessible; } } } }
46 namespace com { namespace sun { namespace star { namespace accessibility { class XAccessibleContext; } } } }
47 namespace com { namespace sun { namespace star { namespace awt { class XFocusListener; } } } }
48 namespace com { namespace sun { namespace star { namespace awt { class XKeyListener; } } } }
49 namespace com { namespace sun { namespace star { namespace awt { class XMouseListener; } } } }
50 namespace com { namespace sun { namespace star { namespace awt { class XMouseMotionListener; } } } }
51 namespace com { namespace sun { namespace star { namespace awt { class XPaintListener; } } } }
52 namespace com { namespace sun { namespace star { namespace awt { class XWindow; } } } }
53 namespace com { namespace sun { namespace star { namespace awt { class XWindowListener; } } } }
54 namespace com { namespace sun { namespace star { namespace awt { struct Point; } } } }
55 namespace com { namespace sun { namespace star { namespace document { class XUndoManager; } } } }
56 namespace com { namespace sun { namespace star { namespace frame { class XDispatch; } } } }
57 namespace com { namespace sun { namespace star { namespace frame { class XLayoutManagerEventBroadcaster; } } } }
58 namespace com { namespace sun { namespace star { namespace lang { class XInitialization; } } } }
59 namespace com { namespace sun { namespace star { namespace uno { class XComponentContext; } } } }
60 namespace com { namespace sun { namespace star { namespace util { class XCloseable; } } } }
61 namespace com { namespace sun { namespace star { namespace view { class XSelectionSupplier; } } } }
62 
63 
64 class SdrModel;
65 
66 namespace svt
67 {
68     class AcceleratorExecute;
69 }
70 
71 namespace svx { namespace sidebar {
72     class SelectionChangeHandler;
73 }}
74 
75 class DropTargetHelper;
76 
77 namespace com { namespace sun { namespace star {
78 namespace graphic {
79     class XGraphic;
80 }
81 }}}
82 
83 namespace chart
84 {
85 
86 class UndoGuard;
87 class ChartWindow;
88 class DrawModelWrapper;
89 class DrawViewWrapper;
90 class ReferenceSizeProvider;
91 class ViewElementListProvider;
92 
93 enum ChartDrawMode { CHARTDRAW_INSERT, CHARTDRAW_SELECT };
94 
95 
96 class ChartController   : public ::cppu::WeakImplHelper <
97          css::frame::XController   //comprehends XComponent (required interface)
98         ,css::frame::XDispatchProvider     //(required interface)
99         ,css::view::XSelectionSupplier     //(optional interface)
100         ,css::ui::XContextMenuInterception //(optional interface)
101         ,css::util::XCloseListener         //(needed for communication with XModel)
102         ,css::lang::XServiceInfo
103         ,css::frame::XDispatch
104         ,css::awt::XWindow //this is the Window Controller part of this Controller, that will be given to a Frame via setComponent
105         ,css::lang::XMultiServiceFactory
106         ,css::util::XModifyListener
107         ,css::util::XModeChangeListener
108         ,css::frame::XLayoutManagerListener
109         >
110 {
111 public:
112     ChartController() = delete;
113     explicit ChartController(css::uno::Reference< css::uno::XComponentContext > const & xContext);
114     virtual ~ChartController() override;
115 
116     OUString GetContextName();
117 
118     // css::lang::XServiceInfo
119     virtual OUString SAL_CALL getImplementationName() override;
120     virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
121     virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
122 
123     // css::frame::XController (required interface)
124     virtual void SAL_CALL
125         attachFrame( const css::uno::Reference< css::frame::XFrame > & xFrame ) override;
126 
127     virtual sal_Bool SAL_CALL
128         attachModel( const css::uno::Reference< css::frame::XModel > & xModel ) override;
129 
130     virtual css::uno::Reference< css::frame::XFrame > SAL_CALL
131         getFrame() override;
132 
133     virtual css::uno::Reference< css::frame::XModel > SAL_CALL
134         getModel() override;
135 
136     virtual css::uno::Any SAL_CALL
137         getViewData() override;
138 
139     virtual void SAL_CALL
140         restoreViewData( const css::uno::Any& rValue ) override;
141 
142     virtual sal_Bool SAL_CALL
143         suspend( sal_Bool bSuspend ) override;
144 
145     // css::lang::XComponent (base of XController)
146     virtual void SAL_CALL
147         dispose() override;
148 
149     virtual void SAL_CALL
150         addEventListener( const css::uno::Reference< css::lang::XEventListener > & xListener ) override;
151 
152     virtual void SAL_CALL
153         removeEventListener( const css::uno::Reference< css::lang::XEventListener > & xListener ) override;
154 
155     // css::frame::XDispatchProvider (required interface)
156     virtual css::uno::Reference< css::frame::XDispatch> SAL_CALL
157         queryDispatch( const css::util::URL& rURL
158                             , const OUString& rTargetFrameName
159                             , sal_Int32 nSearchFlags) override;
160 
161     virtual css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > SAL_CALL
162         queryDispatches( const css::uno::Sequence< css::frame::DispatchDescriptor > & xDescripts) override;
163 
164     // css::view::XSelectionSupplier (optional interface)
165     virtual sal_Bool SAL_CALL
166         select( const css::uno::Any& rSelection ) override;
167 
168     virtual css::uno::Any  SAL_CALL
169         getSelection() override;
170 
171     virtual void SAL_CALL
172         addSelectionChangeListener( const css::uno::Reference< css::view::XSelectionChangeListener > & xListener ) override;
173 
174     virtual void SAL_CALL
175         removeSelectionChangeListener( const css::uno::Reference< css::view::XSelectionChangeListener > & xListener ) override;
176 
177     // css::ui::XContextMenuInterception (optional interface)
178     virtual void SAL_CALL
179         registerContextMenuInterceptor( const css::uno::Reference< css::ui::XContextMenuInterceptor > & xInterceptor) override;
180 
181     virtual void SAL_CALL
182         releaseContextMenuInterceptor( const css::uno::Reference< css::ui::XContextMenuInterceptor > & xInterceptor) override;
183 
184     //additional interfaces
185 
186     // css::util::XCloseListener
187     virtual void SAL_CALL
188         queryClosing( const css::lang::EventObject& Source
189                             , sal_Bool GetsOwnership ) override;
190 
191     virtual void SAL_CALL
192         notifyClosing( const css::lang::EventObject& Source ) override;
193 
194     // css::util::XEventListener (base of XCloseListener and XModifyListener)
195     virtual void SAL_CALL
196         disposing( const css::lang::EventObject& Source ) override;
197 
198     // css::frame::XDispatch
199 
200     virtual void SAL_CALL
201         dispatch( const css::util::URL& aURL
202                     , const css::uno::Sequence< css::beans::PropertyValue >& aArgs ) override;
203 
204     virtual void SAL_CALL
205         addStatusListener( const css::uno::Reference< css::frame::XStatusListener >& xControl
206                     , const css::util::URL& aURL ) override;
207 
208     virtual void SAL_CALL
209         removeStatusListener( const css::uno::Reference< css::frame::XStatusListener >& xControl
210                     , const css::util::URL& aURL ) override;
211 
212     // css::awt::XWindow
213     virtual void SAL_CALL
214         setPosSize( sal_Int32 X, sal_Int32 Y
215                     , sal_Int32 Width, sal_Int32 Height, sal_Int16 Flags ) override;
216 
217     virtual css::awt::Rectangle SAL_CALL
218         getPosSize() override;
219 
220     virtual void SAL_CALL
221         setVisible( sal_Bool Visible ) override;
222 
223     virtual void SAL_CALL
224         setEnable( sal_Bool Enable ) override;
225 
226     virtual void SAL_CALL
227         setFocus() override;
228 
229     virtual void SAL_CALL
230         addWindowListener( const css::uno::Reference< css::awt::XWindowListener >& xListener ) override;
231 
232     virtual void SAL_CALL
233         removeWindowListener( const css::uno::Reference< css::awt::XWindowListener >& xListener ) override;
234 
235     virtual void SAL_CALL
236         addFocusListener( const css::uno::Reference< css::awt::XFocusListener >& xListener ) override;
237 
238     virtual void SAL_CALL
239         removeFocusListener( const css::uno::Reference< css::awt::XFocusListener >& xListener ) override;
240 
241     virtual void SAL_CALL
242         addKeyListener( const css::uno::Reference< css::awt::XKeyListener >& xListener ) override;
243 
244     virtual void SAL_CALL
245         removeKeyListener( const css::uno::Reference< css::awt::XKeyListener >& xListener ) override;
246 
247     virtual void SAL_CALL
248         addMouseListener( const css::uno::Reference< css::awt::XMouseListener >& xListener ) override;
249 
250     virtual void SAL_CALL
251         removeMouseListener( const css::uno::Reference< css::awt::XMouseListener >& xListener ) override;
252 
253     virtual void SAL_CALL
254         addMouseMotionListener( const css::uno::Reference< css::awt::XMouseMotionListener >& xListener ) override;
255 
256     virtual void SAL_CALL
257         removeMouseMotionListener( const css::uno::Reference< css::awt::XMouseMotionListener >& xListener ) override;
258 
259     virtual void SAL_CALL
260         addPaintListener( const css::uno::Reference< css::awt::XPaintListener >& xListener ) override;
261 
262     virtual void SAL_CALL
263         removePaintListener( const css::uno::Reference< css::awt::XPaintListener >& xListener ) override;
264 
265     // css::lang XMultiServiceFactory
266     virtual css::uno::Reference< css::uno::XInterface > SAL_CALL
267         createInstance( const OUString& aServiceSpecifier ) override;
268     virtual css::uno::Reference< css::uno::XInterface > SAL_CALL
269         createInstanceWithArguments( const OUString& ServiceSpecifier,
270                                      const css::uno::Sequence<
271                                          css::uno::Any >& Arguments ) override;
272     virtual css::uno::Sequence< OUString > SAL_CALL
273         getAvailableServiceNames() override;
274 
275     // css::util::XModifyListener
276     virtual void SAL_CALL modified(
277         const css::lang::EventObject& aEvent ) override;
278 
279     // css::util::XModeChangeListener
280     virtual void SAL_CALL modeChanged(
281         const css::util::ModeChangeEvent& _rSource ) override;
282 
283     // css::frame::XLayoutManagerListener
284     virtual void SAL_CALL layoutEvent(
285         const css::lang::EventObject& aSource,
286         ::sal_Int16 eLayoutEvent,
287         const css::uno::Any& aInfo ) override;
288 
289     // WindowController stuff
290     void PrePaint();
291     void execute_Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect);
292     void execute_MouseButtonDown( const MouseEvent& rMEvt );
293     void execute_MouseMove( const MouseEvent& rMEvt );
294     void execute_MouseButtonUp( const MouseEvent& rMEvt );
295     void execute_Resize();
296     void execute_Command( const CommandEvent& rCEvt );
297     bool execute_KeyInput( const KeyEvent& rKEvt );
298 
299     /** get help text to be shown in a quick help
300 
301         @param aAtLogicPosition the position in logic coordinates (of the
302                                 window) of the mouse cursor to determine for
303                                 which object help is requested.
304 
305         @param bIsBalloonHelp determines whether to return the long text version
306                               (balloon help) or the shorter one (quick help).
307 
308         @param rOutQuickHelpText is filled with the quick help text
309 
310         @param rOutEqualRect is filled with a rectangle that denotes the region
311                              in which the quick help does not change.
312 
313         @return </sal_True>, if a quick help should be shown.
314      */
315     bool requestQuickHelp(
316         ::Point aAtLogicPosition, bool bIsBalloonHelp,
317         OUString & rOutQuickHelpText, css::awt::Rectangle & rOutEqualRect );
318 
319     css::uno::Reference< css::accessibility::XAccessible > CreateAccessible();
320 
321     static bool isObjectDeleteable( const css::uno::Any& rSelection );
322 
323     bool isSelectedObjectDraggable() const;
324     bool isSelectedObjectResizable() const;
325     bool isSelectedObjectRotatable() const;
326 
setDrawMode(ChartDrawMode eMode)327     void setDrawMode( ChartDrawMode eMode ) { m_eDrawMode = eMode; }
328 
329     bool isShapeContext() const;
330 
331     ViewElementListProvider getViewElementListProvider();
332     DrawModelWrapper* GetDrawModelWrapper();
333     DrawViewWrapper* GetDrawViewWrapper();
334     VclPtr<ChartWindow> GetChartWindow() const;
335     weld::Window* GetChartFrame();
336     bool isAdditionalShapeSelected() const;
337     void SetAndApplySelection(const css::uno::Reference<css::drawing::XShape>& rxShape);
338     void StartTextEdit( const Point* pMousePixel = nullptr );
339 
340     void NotifyUndoActionHdl( std::unique_ptr<SdrUndoAction> );
341 
342     css::uno::Reference<css::uno::XInterface> const & getChartView() const;
343 
344 private:
345     class TheModel : public salhelper::SimpleReferenceObject
346     {
347         public:
348             explicit TheModel( const css::uno::Reference<
349                         css::frame::XModel > & xModel );
350 
351             virtual ~TheModel() override;
352 
353             void        addListener( ChartController* pController );
354             void        removeListener(  ChartController* pController );
355             void        tryTermination();
356             const css::uno::Reference< css::frame::XModel >&
getModel() const357                         getModel() const { return m_xModel;}
358 
359         private:
360             css::uno::Reference< css::frame::XModel >     m_xModel;
361             css::uno::Reference< css::util::XCloseable >  m_xCloseable;
362 
363             //the ownership between model and controller is not clear at first
364             //each controller might consider himself as owner of the model first
365             bool m_bOwnership;
366     };
367     class TheModelRef final
368     {
369         public:
370             TheModelRef( TheModel* pTheModel, ::osl::Mutex& rMutex );
371             TheModelRef( const TheModelRef& rTheModel, ::osl::Mutex& rMutex );
372             TheModelRef& operator=(ChartController::TheModel* pTheModel);
373             TheModelRef& operator=(const TheModelRef& rTheModel);
374             ~TheModelRef();
375             bool is() const;
operator ->() const376             TheModel* operator->() const { return m_xTheModel.get(); }
377         private:
378             rtl::Reference<TheModel>  m_xTheModel;
379             ::osl::Mutex&             m_rModelMutex;
380     };
381 
382     mutable ::apphelper::LifeTimeManager m_aLifeTimeManager;
383 
384     bool m_bSuspended;
385 
386     css::uno::Reference< css::uno::XComponentContext> m_xCC;
387 
388     //model
389     css::uno::Reference< css::frame::XFrame > m_xFrame;
390     mutable ::osl::Mutex m_aModelMutex;
391     TheModelRef m_aModel;
392 
393     //view
394     css::uno::Reference<css::awt::XWindow> m_xViewWindow;
395     css::uno::Reference<css::uno::XInterface> m_xChartView;
396     std::shared_ptr< DrawModelWrapper > m_pDrawModelWrapper;
397     std::unique_ptr<DrawViewWrapper> m_pDrawViewWrapper;
398 
399     Selection m_aSelection;
400     SdrDragMode m_eDragMode;
401 
402     Timer m_aDoubleClickTimer;
403     bool m_bWaitingForDoubleClick;
404     bool m_bWaitingForMouseUp;
405     bool m_bFieldButtonDown;
406 
407     bool m_bConnectingToView;
408     bool m_bDisposed;
409 
410     css::uno::Reference< css::document::XUndoManager > m_xUndoManager;
411     std::unique_ptr< UndoGuard > m_pTextActionUndoGuard;
412 
413     std::unique_ptr< ::svt::AcceleratorExecute > m_apAccelExecute;
414 
415     CommandDispatchContainer m_aDispatchContainer;
416 
417     std::unique_ptr< DropTargetHelper > m_apDropTargetHelper;
418     css::uno::Reference<
419             css::frame::XLayoutManagerEventBroadcaster > m_xLayoutManagerEventBroadcaster;
420 
421     ChartDrawMode m_eDrawMode;
422 
423     rtl::Reference<svx::sidebar::SelectionChangeHandler> mpSelectionChangeHandler;
424 
425     bool impl_isDisposedOrSuspended() const;
426     std::unique_ptr<ReferenceSizeProvider> impl_createReferenceSizeProvider();
427     void impl_adaptDataSeriesAutoResize();
428 
429     void impl_createDrawViewController();
430     void impl_deleteDrawViewController();
431 
432     //executeDispatch methods
433     void executeDispatch_ObjectProperties();
434     void executeDispatch_FormatObject( const OUString& rDispatchCommand );
435     void executeDlg_ObjectProperties( const OUString& rObjectCID );
436     bool executeDlg_ObjectProperties_withoutUndoGuard( const OUString& rObjectCID, bool bSuccessOnUnchanged );
437 
438     void executeDispatch_ChartType();
439 
440     void executeDispatch_InsertTitles();
441     void executeDispatch_InsertLegend();
442     void executeDispatch_DeleteLegend();
443     void executeDispatch_OpenLegendDialog();
444     void executeDispatch_InsertAxes();
445     void executeDispatch_InsertGrid();
446 
447     void executeDispatch_InsertMenu_DataLabels();
448     void executeDispatch_InsertMenu_Trendlines();
449     void executeDispatch_InsertMenu_MeanValues();
450 
451     void executeDispatch_InsertMeanValue();
452     void executeDispatch_InsertTrendline();
453     void executeDispatch_InsertTrendlineEquation( bool bInsertR2=false );
454     void executeDispatch_InsertErrorBars( bool bYError );
455 
456     void executeDispatch_InsertR2Value();
457     void executeDispatch_DeleteR2Value();
458 
459     void executeDispatch_DeleteMeanValue();
460     void executeDispatch_DeleteTrendline();
461     void executeDispatch_DeleteTrendlineEquation();
462     void executeDispatch_DeleteErrorBars( bool bYError );
463 
464     void executeDispatch_InsertDataLabels();
465     void executeDispatch_InsertDataLabel();
466     void executeDispatch_DeleteDataLabels();
467     void executeDispatch_DeleteDataLabel();
468 
469     void executeDispatch_ResetAllDataPoints();
470     void executeDispatch_ResetDataPoint();
471 
472     void executeDispatch_InsertAxis();
473     void executeDispatch_InsertAxisTitle();
474     void executeDispatch_InsertMajorGrid();
475     void executeDispatch_InsertMinorGrid();
476     void executeDispatch_DeleteAxis();
477     void executeDispatch_DeleteMajorGrid();
478     void executeDispatch_DeleteMinorGrid();
479 
480     void executeDispatch_InsertSpecialCharacter();
481     void executeDispatch_EditText( const Point* pMousePixel = nullptr );
482     void executeDispatch_SourceData();
483     void executeDispatch_MoveSeries( bool bForward );
484 
485     bool EndTextEdit();
486 
487     void executeDispatch_View3D();
488     void executeDispatch_PositionAndSize( const ::css::uno::Sequence< ::css::beans::PropertyValue >* pArgs = nullptr );
489 
490     void executeDispatch_EditData();
491 
492     void executeDispatch_NewArrangement();
493     void executeDispatch_ScaleText();
494 
495     void executeDispatch_Paste();
496     void executeDispatch_Copy();
497     void executeDispatch_Cut();
498     bool executeDispatch_Delete();
499     void executeDispatch_ToggleLegend();
500     void executeDispatch_ToggleGridHorizontal();
501     void executeDispatch_ToggleGridVertical();
502 
503     void executeDispatch_LOKSetTextSelection(int nType, int nX, int nY);
504     void executeDispatch_LOKPieSegmentDragging(int nOffset);
505 
506     void sendPopupRequest(OUString const & rCID, tools::Rectangle aRectangle);
507 
508     void impl_ShapeControllerDispatch( const css::util::URL& rURL,
509         const css::uno::Sequence< css::beans::PropertyValue >& rArgs );
510 
511     DECL_LINK( DoubleClickWaitingHdl, Timer*, void );
512     void execute_DoubleClick( const Point* pMousePixel );
513     void startDoubleClickWaiting();
514     void stopDoubleClickWaiting();
515 
516     void impl_selectObjectAndNotiy();
517     void impl_notifySelectionChangeListeners();
518     void impl_invalidateAccessible();
519     void impl_initializeAccessible();
520     void impl_initializeAccessible( const css::uno::Reference< css::lang::XInitialization >& xInit );
521 
522     //sets the model member to null if it equals the parameter
523     //returns true if successful
524     bool impl_releaseThisModel( const css::uno::Reference< css::uno::XInterface > & xModel );
525 
526     enum eMoveOrResizeType
527     {
528         MOVE_OBJECT,
529         CENTERED_RESIZE_OBJECT
530     };
531     /// @return </sal_True>, if resize/move was successful
532     bool impl_moveOrResizeObject(
533         const OUString & rCID, eMoveOrResizeType eType, double fAmountLogicX, double fAmountLogicY );
534     bool impl_DragDataPoint( const OUString & rCID, double fOffset );
535 
536     static const std::set< OUString >& impl_getAvailableCommands();
537 
538     /** Creates a helper accessibility class that must be initialized via XInitialization.  For
539         parameters see
540 
541         The returned object should not be used directly.  Instead a proxy object
542         should use this helper to retrieve its children and add them to its own
543         children.
544      */
545     css::uno::Reference< css::accessibility::XAccessibleContext >
546         impl_createAccessibleTextContext();
547 
548     void impl_PasteGraphic( css::uno::Reference< css::graphic::XGraphic > const & xGraphic,
549                             const ::Point & aPosition );
550     void impl_PasteShapes( SdrModel* pModel );
551     void impl_PasteStringAsTextShape( const OUString& rString, const css::awt::Point& rPosition );
552     void impl_SetMousePointer( const MouseEvent & rEvent );
553 
554     void impl_ClearSelection();
555 
556     void impl_switchDiagramPositioningToExcludingPositioning();
557 };
558 
559 }  // namespace chart
560 
561 #endif
562 
563 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
564